我如何完成K&R练习2-4?

我正在学习如何使用k&r书(C语言编程语言)在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'; } 

好书。 如果我是你,我会完全按照第2.8节中的squeeze()进行操作,但不是直接比较(s [i]!= c)我会编写并利用一个函数

  int contains(char s[], int c) 

如果字符串s包含c则返回1,否则返回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'; } } 

这是我的function:

 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'; }