【问题标题】:Why am I experiencing an infinite loop here?为什么我在这里遇到无限循环?
【发布时间】:2022-01-07 08:56:50
【问题描述】:

我的代码永远不会停止要求输入,所以我想我一定是做了一个无限循环,但我找不到错误在哪里。我还注意到,当逐行插入输入时,它会在插入第二个循环的第一行后打印一个循环的结果,这对我来说似乎不正确。请帮我调试。 (对于进一步的上下文,代码应该接收一个我们称之为 n 的数字,然后再扫描 3n 行,基本上是 n 束 3 行相似的行。第 2 行和第 3 行是具有相同字符数的两个单词, 第一行就是那个 num。输出是这些词是否是字谜。)

#include <stdio.h>

int main() {
    int n, l;

    scanf("%d\n", &n);

    for (int i = 1; i <= n; i++) {
        scanf("%d\n", &l);
        char A[l], B[l];

        for (int j = 0; j < l; j++) {
            scanf("%c", &A[j]);
            scanf("\n");
        }
        for (int j = 0; j < l; j++) {
            scanf("%c", &B[j]);
            scanf("\n");
        }

        for (int k = 0; k < l; k++) {
            int result = 0;
            for (int j = 0; j < l; j++) {
                if (A[k] == B[j]) {
                    result = 1;
                }
            }
            if (!result) {
                printf("\nNO\n");
                return 0;
            }
        }

        printf("\nYES\n");
    }
}

例子:

输入:

2
6
listen
silent
4
Evil
live

输出:

YES
NO

【问题讨论】:

  • 你能发一个输入的例子吗?
  • evillive等的每个字母是单独输入还是只在整个单词后按回车?
  • 你认为abbbbbbaaaaaab是“由相同的字母组成”吗?
  • @Gerhardh 将每个空格计为换行符,因此每个单词都在一行而不是每个字符。不,这些词必须是字谜。它也区分大小写,因此第二个示例接收“NO”作为其输出。
  • 为什么听和默前有2个不同的数字,我以为是1个数字后跟2个字?

标签: c visual-studio-code


【解决方案1】:

您的scanf 调用会等待额外的\n,这需要更多输入才能输入。

要解决此问题,请从您的 scanf 调用中删除 \n。输入AB时也去掉多余的调用:

我添加了一些调试代码来演示您在输入输入时执行程序的位置。

#include <stdio.h>

int main() {
    int n, l;
    int res;

    res=scanf("%d", &n);

printf ("res=%d, n=%d\n", res, n);

    for (int i = 1; i <= n; i++) {
        res = scanf("%d", &l);

printf ("res=%d, l=%d\n", res, l);

//        char A[l], B[l];
        char A[l+1], B[l+1];

        for (int j = 0; j < l; j++) {
            scanf(" %c", &A[j]);
        }      

printf ("A done\n");

        for (int j = 0; j < l; j++) {
            scanf(" %c", &B[j]);
        }

printf ("B done\n");

A[l] = 0; B[l] = 0;
printf ("A=\"%s\" - B=\"%s\"\n", A, B);
...

现在您的输入应该可以正常工作了。

但您的代码还包含另一个错误。 您会将"12344""11234" 视为正确匹配,而这是错误的。

要解决此问题,您需要从 B 中删除每个匹配的字符:

        for (int k = 0; k < l; k++) {
            int result = 0;

// We compare A[k] with the remaining characters in B only
            for (int j = k; j < l; j++) {
                if (A[k] == B[j]) {
                    result = 1;
                    B[j] = B[k]; // Replace matching character with non-matching character we checked earlier.
                    break;
                }
            }
            if (!result) {
                printf("\nNO\n");
                return 0;
            }
        }

        printf("\nYES\n");

一旦找到第一个匹配项并从B 中删除该字符,此代码就会停止。 B 中的条目被重新排列以将未使用的条目保留在末尾。

完整的代码如下所示:

#include <stdio.h>

int main() {
    int n, l;
    int res;

    res=scanf("%d", &n);

printf ("res=%d, n=%d\n", res, n);

    for (int i = 1; i <= n; i++) {
        res = scanf("%d", &l);

printf ("res=%d, l=%d\n", res, l);

//        char A[l], B[l];
        char A[l+1], B[l+1];

        for (int j = 0; j < l; j++) {
            scanf(" %c", &A[j]);
        }      

printf ("A done\n");

        for (int j = 0; j < l; j++) {
            scanf(" %c", &B[j]);
        }

printf ("B done\n");

A[l] = 0; B[l] = 0;
printf ("A=\"%s\" - B=\"%s\"\n", A, B);
        

        for (int k = 0; k < l; k++) {
            int result = 0;
            for (int j = k; j < l; j++) {
                if (A[k] == B[j]) {
                    result = 1;
                    B[j] = B[k];
                    break;
                }
            }
            if (!result) {
                printf("\nNO\n");
                return 0;
            }
        }

        printf("\nYES\n");
    }
}

输出:

~/stackoverflow$ ./test
4
res=1, n=4
2
res=1, l=2
12
A done
21
B done
A="12" - B="21"

YES
6
res=1, l=6
liver1
A done
evil1r
B done
A="liver1" - B="evil1r"

YES
3
res=1, l=3
111
A done
111
B done
A="111" - B="111"

YES
4
res=1, l=4
abcd
A done
dcbb
B done
A="abcd" - B="dcbb"

NO

【讨论】:

  • 谢谢,虽然当我完全删除 \n 扫描仪时,每个 \n 都变成了一个数组字符,所以我为最后一个 \n 添加了一个 if 条件。现在它在一个额外的 \n 之后给出输出,我认为这很好。显然我在其他地方还有另一个问题。只是给了它一个更大的 n (n = 4),它仍然只给了我 2 个输出而不是 4 个。知道为什么吗?
  • 我的版本也适用于 n=4。查看更新。
  • 这很奇怪,因为我只是复制粘贴了您的确切代码,尽管它确实为我的输入提供了 4 个输出,但它们是错误的,并且您分配给它的其他内容都没有打印打印。非常感谢您的帮助,希望我能弄清楚这一点。
  • 听起来好像你编译了别的东西……
【解决方案2】:

这是因为你一遍又一遍地要求输入,

不确定您要达到什么目的,但首先要删除多余的scanfs

试试这个,

#include <stdio.h>

int main() {
    int n, l;

    scanf("%d\n", &n);

    for (int i = 1; i <= n; i++) {
        char A[l], B[l];


        for (int k = 0; k < l; k++) {
            int result = 0;
            for (int j = 0; j < l; j++) {
                if (A[k] == B[j]) {
                    result = 1;
                }
            }
            if (!result) {
                printf("\nNO\n");
                return 0;
            }
        }

        printf("\nYES\n");
    }
}

【讨论】:

  • 我正在使用另外 2 个 scanfs 来接收两个单词作为数组。代码的重点是比较这两个单词,看看它们是否由同一组字母组成。根据我的调试器,我认为代码在接收单词时没有问题,数组是正确的,结果也是正确的,直到最后一组。这就是为什么我认为我的循环有问题?
  • @Maya 你能发一个输入的例子吗?
  • 您删除了 AB 的所有输入,当您比较未初始化的变量时,这会导致未定义的行为
  • @anarchy 我已将其添加到我的原始帖子中
猜你喜欢
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
  • 2020-08-08
  • 2016-03-02
  • 2021-09-19
相关资源
最近更新 更多