【问题标题】:String manipulation (variable output with the same input)字符串操作(具有相同输入的变量输出)
【发布时间】:2018-05-23 21:16:15
【问题描述】:

也许某些属性在我没有注意到的情况下传递,但是当 'i' 为 1 时,它就会冻结。当我输入任何字符串时,'j' 变量在不同的执行中变为 700 或 2000。如果输入“cheese”,则代码目标是输出重复的字母,输出应为“eee”。我做错了什么?

    #include <stdio.h>
    char * repeticoes(char *s) {
        int index = 0;

        for (int i = 0;( s[i] != '\0'); i++) //problem starts when i is > 0
        {
            for (int j = 0; ( s[j] != '\0'); j++)
            {
                if (s[i] == s[j])
                {
                    printf("%c == %c\ni %d  j %d\n", s[i], s[j],i,j);
                    s[index++] = s[i];

                }
                else
                {
                    printf("not happening %c != %c\ni %d  j %d\n", s[i],s[j],i,j);
                }
            }

        }

        s[++index] = '\0';
        return s;
    }

    main() {
        char input[21];

        printf("str 1\n");
        fgets(input, 20, stdin);
        repeticoes(input);
        printf("duplicated letters %s\n", input);

    }

【问题讨论】:

  • 你有什么意见?
  • 也许你的 s[index++] = s[i],覆盖了终止的零,因此循环永远不会到达终点,尽管我可能会误会。
  • @EugeneSh。奶酪,但任何输入都会产生意想不到的输出
  • @kingW3 不明白为什么,但我应该改变什么?
  • s[index++] = s[i];是错的。您正在修改输入字符串。这可能会导致字符串末尾的 0 被覆盖,并导致缓冲区溢出。而是使用其他缓冲区来复制字符。

标签: c string function


【解决方案1】:

您需要在外循环中处理的字符之后的下一个字符处开始内循环,否则您将处理同一对字符两次,以及在i == j 时针对自身测试一个字符。

您还应该在找到匹配项后立即跳出内部循环。您将在外部循环的未来迭代中找到稍后的匹配项。否则,您将再次处理同一对两次。

在循环之后分配空字符之前,您不应该增加index。添加重复时已递增。

#include <stdio.h>
char * repeticoes(char *s) {
    int index = 0;

    for (int i = 0;( s[i] != '\0'); i++) //problem starts when i is > 0
    {
        for (int j = i+1; ( s[j] != '\0'); j++)
        {
            if (s[i] == s[j])
            {
                printf("%c == %c\ni %d  j %d\n", s[i], s[j],i,j);
                s[index++] = s[i];
                break;
            }
            else
            {
                printf("not happening %c != %c\ni %d  j %d\n", s[i],s[j],i,j);
            }
        }

    }

    s[index] = '\0';
    return s;
}

int main() {
    char input[21];

    printf("str 1\n");
    fgets(input, 20, stdin);
    repeticoes(input);
    printf("duplicated letters %s\n", input);

}

【讨论】:

  • 已经取得了一些进展,但它没有完全起作用,当我写“爆米花”时它返回“pop”但应该是“popo”或者如果我输入“invisibility”它返回“iiiis”应该是“iii”
  • 这让它变得更加复杂,因为你需要一些方法来防止它两次报告相同的字母。
  • invisibility 中,第三个 i 匹配第一个 i 和第二个 i。第 4 个 i 匹配第 1 个、第 2 个和第 3 个 i。
  • 修复s[++index] = '\0';后,输出为po。它只返回字符的重复,而不是它们的原始出现。
  • 更好的方法是制作一个包含每个字符重复计数的表。然后返回一个字符串,其中包含所有计数大于 1 的字符,重复那么多字符。
【解决方案2】:

有一个要计数的字母数组和一个计数数组。计算完字母后,再次循环输入并设置计数大于 1 的字母。

#include <stdio.h>

void repeticoes ( char *s) {
    char tocount[] = "abcdefghijklmnopqrstuvwxyz";
    size_t len = sizeof tocount;
    size_t index = 0;
    int count[len];

    for (int j = 0; j < len; j++) {
        count[j] = 0;
    }

    for (int i = 0;( s[i] != '\0'); i++) {
        for (int j = 0; j < len; j++) {
            if ( s[i] == tocount[j]) {
                count[j]++;
            }
        }
    }
    for (int i = 0;( s[i] != '\0'); i++) {
        for (int j = 0; j < len; j++) {
            if ( s[i] == tocount[j] && 1 < count[j]) {
                s[index] = s[i];
                index++;
            }
        }
    }
    s[index] = '\0';
}

int main ( void) {
    char input[21];

    printf("str 1\n");
    fgets(input, 20, stdin);
    repeticoes(input);
    printf("duplicated letters %s\n", input);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多