Как завершить K & R Exercise 2-4?

Я изучаю, как писать программы на C, используя книгу k & r (язык программирования C), и у меня есть проблема с одним из упражнений. Он просит меня обнаружить и удалить символ в строке s1, который соответствует любым символам в строке s2.

Итак, скажем s1 = “A”;

И s2 = “AABAACAADAAE”

Я хочу, чтобы он возвращал “BCDE”

Я знаю, что я нахожусь на правильном пути к этому, я просто не знаю, как правильно проектировать программы, не могли бы вы дать мне дополнительные советы. Я попытался прочитать алгоритм дерева двоичного поиска, но чувствовал, что он слишком продвинут для этой мирской задачи.

Спасибо всем!

/* An alternate version of squeeze(s1, s2) that deletes each character in * s1 that matches any character in the string s2 * * Angie@odfx.org */ #include  #include  void squeeze(char s[], char t[]); char string[] = "BAD"; char sstring[] = "ABC"; int main(void) { squeeze(string, sstring); return 0; } void squeeze(char s[], char t[]) { int i, j, d; d = 0; if(strstr(s, t) == NULL) printf("%c", s[i]); s[j] = '\0'; } 

Отличная книга. Если бы я был вами, я бы пошел точно так же, как и для squeeze () в разделе 2.8, но вместо прямого сравнения (s [i]! = C) я написал бы и использовал бы функцию

  int contains(char s[], int c) 

который возвращает 1, если строка s содержит c, 0 в противном случае. Начните с простого подхода; когда он работает, вы можете повысить производительность с помощью более сложных решений (двоичный поиск, но обратите внимание, что проблема не требует, чтобы символы в s2 были в определенном порядке).

Для этого двоичный поиск – это слишком много. Вам нужны три индекса. Один индекс ( i ), проходящий через s , один индекс ( k ), проходящий по t , и один индекс ( j ), чтобы отслеживать, где вы находитесь, для символов, которые вам нужно сохранить, потому что они не находятся в t . Итак, для каждого символа в s проверьте и проверьте, находится ли он в t . Если это не так, сохраните его в s .

 void squeeze(char *s, char *t) { int i, j, k; int found = 0; for(i = j = 0; s[i] != '\0'; i++) { found = 0; for(k = 0; t[k] != '\0' && (found == 0); k++) { if(t[k] == s[i]) { found = 1; } } if(found == 0) { s[j++] = s[i]; } } s[j] = '\0'; } 

Вам не нужен фантастический двоичный поиск, чтобы выполнить эту работу. Вам нужен двойной цикл, который проверяет наличие каждого символа в одной строке в другой и копирует не встречающиеся символы в третий массив символов (который является вашим результатом).

Код может быть примерно следующим (не проверен!):

 char *s1, *s2, *result; /* original strings and the result string */ int len1, len2; /* lengths of the strings */ for (i = 0; i < len1; i++) { for (j = 0; j < len2; j++) { if (s1[i] == s2[j]) { break; } } if (j == len2) { /* s1[i] is not found in s2 */ *result = s1[i]; result++; /* assuming your result array is long enough */ } } 
 void squeeze(char s1[], char s2[]) { int i,j,k; char c; for(i=0;s2[i]!='\0';i++) { c=s2[i]; for(j=k=0;s1[j]!='\0';j++) if(s1[j]!=c) s1[k++]=s1[j]; s1[k]='\0'; } } 

это моя функция:

 void squeeze(char s1[],char s2[]) { int i,j,p; int found; p=0; for(i=0;s1[i]!='\0';i++) { for(j=0;s2[j]!='\0';j++) if(s1[i]==s2[j]) found=YES; else found=NO; if(found==NO) s1[p++]=s1[i]; } s1[p]='\0'; }