【问题标题】:How do I complete K&R Exercise 2-4?如何完成 K&R 练习 2-4?
【发布时间】:2010-09-29 22:52:47
【问题描述】:

我正在学习如何使用 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 <stdio.h>
#include <string.h>

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

【问题讨论】:

  • 过于本地化,但我们将关闭 another question 作为此副本的副本。伙计们,不要太高兴了。其他 Q 的访客,请在这里投票重新开放。

标签: c string kernighan-and-ritchie


【解决方案1】:

这是我的功能:

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

【讨论】:

    【解决方案2】:
    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';
        }
    }
    

    【讨论】:

    • 与2.8节中的squeeze()写法相同,稍作修改
    【解决方案3】:

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

     int contains(char s[], int c)
    

    如果字符串 s 包含 c,则返回 1,否则返回 0。从简单的方法开始;当它起作用时,您可以使用更复杂的解决方案来提高性能(二进制搜索,但请注意,该问题不需要 s2 中的字符按特定顺序排列)。

    【讨论】:

    • 另外,我不认为二分搜索值得。毕竟可能的字符只有255个……
    【解决方案4】:

    二分查找对于这个来说太过分了。你需要三个索引。一个索引 (i) 遍历 s,一个索引 (k) 遍历 t,一个索引 (j) 跟踪您在 s 中的位置您需要保留,因为它们不在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';
    }
    

    【讨论】:

      【解决方案5】:

      您不需要花哨的二进制搜索来完成这项工作。您需要的是一个双 for 循环,它检查一个字符串中的每个字符是否出现在另一个字符串中,并将未出现的字符复制到第三个字符数组中(这是您的结果)。

      代码可能类似于以下内容(未经测试!):

      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 */
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-25
        • 2015-01-14
        • 1970-01-01
        相关资源
        最近更新 更多