为什么-doesn&#t; t-while循环无休止地循环?

时间:2017-10-06 04:01:42

标签: c

*编辑附加到帖子底部。

我尝试在C中生成一些代码,生成一个包含10行和2列的2D数组。我创建了一个检查,以查看在生成行时,如果它与另一个现有行相同,它将继续更改它的值,直到它成为新的唯一行。

我目前将最大变量设置为1,以便验证while循环永远不会终止,因为它可能找不到10个唯一的0和1组合。这段代码确实找到重复并相应地改变,但似乎最终跳过检查并终止,而不是像它应该无休止地循环。 printf函数用于探测我的代码的行为。

为什么我的while循环终止?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int main (int argc, char *argv[]) {
    int max_x = 1, max_y = 1;
    int num_pt = 10;
    int array[num_pt][2];
    srand(time(0));

    //Generate a new file
    if (argc == 1) {
        printf("Generating instances\n");
        for (int i = 0 ; i < num_pt ; i++) {
            array[i][0] = rand()%(max_y+1);
            array[i][1] = rand()%(max_x+1);
            for (int j = i-1 ; j >= 0 ; j-- ) {
                while ((array[i][0] == array[j][0]) && (array[i][1] == array[j][1])) {
                    printf("\narray[%d][0]/[%d][1] and array[%d][0]/[%d][1]: Duplicate exists", i, i, j, j);
                    array[i][0] = rand()%(max_y+1);
                    array[i][1] = rand()%(max_x+1);
                }
            }
        }
        for (int j = 0 ; j < num_pt ; j++) {
            printf("\nRow[%d] = [%d][%d]", j, array[j][0], array[j][1]);
        }
    return 1;
    }
}

示例输出:

Generating instances

array[2][0]/[2][1] and array[0][0]/[0][1]: Duplicate exists
array[2][0]/[2][1] and array[0][0]/[0][1]: Duplicate exists
array[3][0]/[3][1] and array[1][0]/[1][1]: Duplicate exists
array[4][0]/[4][1] and array[1][0]/[1][1]: Duplicate exists
array[5][0]/[5][1] and array[1][0]/[1][1]: Duplicate exists
array[6][0]/[6][1] and array[4][0]/[4][1]: Duplicate exists
array[6][0]/[6][1] and array[2][0]/[2][1]: Duplicate exists
array[6][0]/[6][1] and array[0][0]/[0][1]: Duplicate exists
array[7][0]/[7][1] and array[6][0]/[6][1]: Duplicate exists
array[7][0]/[7][1] and array[0][0]/[0][1]: Duplicate exists
array[8][0]/[8][1] and array[4][0]/[4][1]: Duplicate exists
array[8][0]/[8][1] and array[2][0]/[2][1]: Duplicate exists
array[8][0]/[8][1] and array[0][0]/[0][1]: Duplicate exists
array[9][0]/[9][1] and array[8][0]/[8][1]: Duplicate exists
array[9][0]/[9][1] and array[6][0]/[6][1]: Duplicate exists
array[9][0]/[9][1] and array[6][0]/[6][1]: Duplicate exists
array[9][0]/[9][1] and array[0][0]/[0][1]: Duplicate exists
array[9][0]/[9][1] and array[0][0]/[0][1]: Duplicate exists
Row[0] = [1][1]
Row[1] = [1][0]
Row[2] = [0][0]
Row[3] = [0][1]
Row[4] = [0][1]
Row[5] = [0][0]
Row[6] = [1][0]
Row[7] = [0][0]
Row[8] = [0][1]
Row[9] = [0][1]

------------------
(program exited with code: 1)
Press return to continue

感谢您的帮助。昨晚我躺在床上思考它时,我终于明白了。我的解决方案是添加一个计数器,如果它找到任何冗余的行,它将重新运行整个检查。

int main (int argc, char *argv[]) {
    int max_x = 2, max_y = 2;
    int num_pt = 9;
    int array[num_pt][2];
    srand(time(0));
    int rerun = 1;

    //Generate a new file
    if (argc == 1) {
        printf("Generating instances\n");
        for (int i = 0 ; i < num_pt ; i++) {
            array[i][0] = rand()%(max_y+1);
            array[i][1] = rand()%(max_x+1);
            rerun++;
            while (rerun != 0) {
                rerun = 0;
                for (int j = i-1 ; j >= 0 ; j-- ) {
                    if (array[i][0] == array[j][0] && array[i][1] == array[j][1]) {
                        printf("\narray[%d][0]/[%d][1] and array[%d][0]/[%d][1]: Duplicate exists", i, i, j, j);
                        array[i][0] = rand()%(max_y+1);
                        array[i][1] = rand()%(max_x+1);
                        rerun++;
                    }
                }
            }
        }
        for (int j = 0 ; j < num_pt ; j++) {
            printf("\nRow[%d] = [%d][%d]", j, array[j][0], array[j][1]);
        }
    return 1;
    }
}

这种方式有效,但如果有人有更有效的方式做到这一点,那我就是全部。

2 个答案:

答案 0 :(得分:1)

循环次序错误。

你的内部while循环只会反复检查同一对,直到找到该特定对的有效组合。

如果确实如此,它可能已经破坏了与其他元素的兼容性。由于你的外环和中环永远不会重新访问曾经工作过一次的对,所以这完全没有被注意到。

答案 1 :(得分:0)

很简单,当您尝试查看第i行和第j行是否相似时,您可以更改第i行中的值。

然后j = j - 1.现在将这个新j与行i进行比较。如果这些碰巧相似,那么你再次改变第i行,但这次你没有看到行j的先前值。

创建新行时,必须记住每行的所有使用值。但是目前的算法一次只能看两行。

以下是我所说的情况,

      1 0
j  -- 0 1
i  -- 0 1

row i == row j, change row i

      1 0
j  -- 0 1
i  -- 1 0

j --;

j  -- 1 0
      0 1
i  -- 1 0

row i == row j, change row i

j --  1 0
      0 1
i  -- 0 1

这里循环中断正确,因为行i!=行j但行i-1仍然类似于行i。