2010-04-12 3 views
3

Мне нужно написать программу, которая принимает две строки в качестве аргументов и проверяет, является ли вторая подстрокой первой. Мне нужно сделать это без использования каких-либо специальных функций библиотеки. Я создал эту реализацию, но я думаю, что она всегда возвращает true, если в обеих строках одна и та же. Вы можете помочь мне здесь. Я не уверен, что я делаю неправильно:C - проверить, является ли строка подстрокой другой строки

#include <stdio.h> 
#include <string.h> 

int my_strstr(char const *s, char const *sub) { 
    char const *ret = sub; 

    int r = 0; 
    while (ret = strchr(ret, *sub)) { 
     if (strcmp(++ret, sub+1) == 0){ 
      r = 1; 
     } 
     else{ 
      r = 0; 
     }   
    } 
    return r; 
} 

int main(int argc, char **argv){ 

    if (argc != 3) { 
     printf ("Usage: check <string one> <string two>\n"); 
    } 
    int result = my_strstr(argv[1], argv[2]); 

    if(result == 1){ 
     printf("%s is a substring of %s\n", argv[2], argv[1]); 
    } else{ 
     printf("%s is not a substring of %s\n", argv[2], argv[1]); 
    } 
    return 0; 
} 
+4

Если вам «нужно сделать это без использования каких-либо специальных функций библиотеки», то вам не следует использовать strchr и strcmp. на самом деле strcmp - это то, где ваша проблема в любом случае. – stmax

+0

@stmax: Это просто функции _ordinary_ library. В них нет ничего особенного :) –

+0

@ Daniel: если 'strchr()' и 'strcmp()' являются обычными, то есть 'strstr()' ... –

ответ

1

Ну, вы не должны модифицировать ret в my_strstr. И strcmp не сравнивает подстроки, сравнивает строки. Возможно, вы захотите использовать strncmp.

0

Похоже, что вы ищете полукокс * подразделы в полукоксе * подразделах:

int my_strstr(char const *s, char const *sub) { 
char const *ret = sub; 

не вы должны быть настройками в отставке, чтобы с?

Также strcmp сравнивает строки, а не подстроки, поэтому strcmp ("abcde", "abc") возвращает false. Вы, вероятно, хотите strncmp, который также принимает целое число, определяющее длину.

3

Ваш подход к написанию strstr в корне ошибочен. Давайте посмотрим на то, что Вы писали:

char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 
    if (strcmp(++ret, sub+1) == 0){ 
     r = 1; 
    } 
    else{ 
     r = 0; 
    }   
} 
return r; 

Прежде всего, так как вы инициализировать ret, чтобы указать на sub, вы сравниваете sub против себя, и никогда не смотрит на s. Но давайте предположим, что вы имели в виду для ret быть инициализирована s ...

ret = strchr(ret, *sub) находит положение следующего характера sub в ret, а затем переходит ret так, что она начинается с этого символа.

Затем вы выполняете strcmp(++ret, sub+1), который определяет, если строка, начиная со следующего характера ret равно строки, начиная со следующего характера sub, а затем переходит ret начать со следующего символа (независимо от того, будет ли тест было истинным или ложным).

Очевидно, что эта логика не делает то, что вы хотите. Фактически это будет означать, что подстрока либо равна строке s, либо находится на конце строки s и не содержит повторяющихся букв.

Вот общая схема алгоритма вы хотите:

  1. Найти позицию первого символа sub в s. Если не найдено, верните false.
  2. Update s так, что он начинается с этой позиции
  3. Предполагая, что длина sub является n, тест, если первые n символы s матча sub (стараясь не бежать мимо конца s). Если это так, верните true. В противном случае, вперед s одним символом и петлей.

Обратите внимание, что вы никогда не должны искать ни одного символа в sub, кроме первого. Идея состоит в том, чтобы использовать первый символ sub, чтобы найти потенциал начальные позиции для sub в s, а затем проверить, существует ли там подстрока sub. Если его там нет, вы должны отбросить всю сумму s до этой точки, а затем начать сначала, пытаясь найти следующую потенциальную стартовую позицию.

0

Когда

ret = strchr(ret, *sub) 

впервые встречается, ret == sub. Таким образом, strchr(ret, *sub) выполняет поиск первое появление первого символа ret в ret. Который вернет ret.

Таким образом, ret остается без изменений.

Далее

strcmp(++ret, sub+1) == 0 

ret по-прежнему равна sub, поэтому приведенное выше утверждение верно .

И вы получите 1 в качестве возврата.

0

Это может помочь разбить эту задачу немного по-другому. Для этой задачи есть две ключевые части: 1) поиск начальной точки возможных подстрочных совпадений и 2) проверка того, действительно ли эта начальная точка является соответствующей подстрокой. Поэтому реализуйте это как две функции.

Сначала создайте функцию, которая определяет, являются ли две строки точно одинаковыми. Это должно быть относительно легко закодировать, просто сравните первую букву с первой буквой, вторую со второй и т. Д. Если вы найдете два, которые не совпадают, верните false. Если вы дойдете до конца одной из строк, верните true. Если вам разрешено использовать strncmp, тогда это будет просто (strncmp(a, b, strlen(b)) == 0) (при условии, что b всегда является более короткой строкой).

Во-вторых, создайте функцию, проходящую через строку, ища определенную букву. Всякий раз, когда он находит эту букву, она вызывает функцию и передает указатель на эту букву в строке. Другими словами, если вы вызвали my_function("This is a sample string", 's'), функция должна пройти через строку, найти все четыре экземпляра буквы 's' и вызвать функцию, используя указатель на эту букву в строке. В этом случае функция, которую вы вызываете, - это функция, описанная в предыдущем абзаце.

Используя этот отказ, вы вернете «истину», как только любой из вызовов подфункции вернется «истина», или вы вернете «ложь», если вы дойдете до конца входной строки.

0
char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 

RET хранит адрес суб массива и в в то время как оператор strchr(ret,*sub) сравнивая значение в sub с адресом, хранящимся в ret будет ли это работать или нет (это сравнение верно или нет) ответ кто-нибудь, пожалуйста, ...

Смежные вопросы