我的数独生成c中的代码出了什么问题?

时间:2016-04-08 21:34:55

标签: c sudoku

这是我的作业,制作数独游戏。我已经完成了算法,但它正在进入无限循环。我不明白为什么。

我正在尝试创建一个随机数并控制它以查找真实数字。检查所有列和行以查找与我们的随机数相同的数字(如果是),它正在更改测试编号,如果测试已更改,则尝试找到另一个数字作为真实编号。简单的数独逻辑。

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

int main() {
  srand(time(NULL));
  int num, col, row, row2, col2, test = 0;
  int sudo[9][9] = {{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0}};

  for (row = 0; row <= 8; row++) {
    for (col = 0; col <= 8; col++) {
      do {
        test = 0;
        num = rand() % 9 + 1;
        //control
        for (col2 = 0; col2 <= 8; col2++) {
          if (num == sudo[col2][row]) {
            test++;
          }
        }
        for (row2 = 0; row2 <= 8; row2++) {
          if (num == sudo[col][row2]) {
            test++;
          }
        }
      } while (test > 0);
      sudo[col][row] = num;
    }
  }
//print
  for (row = 0; row <= 8; row++) {
    for (col = 0; col <= 8; col++) {
      printf(" %d ", sudo[col][row]);
      if (col == 2 || col == 5) {
        printf(" | ");
      }
    }
    if (row == 2 || row == 5) {
      printf("\n---------------------------------");
    }
    printf("\n");
  }
}

1 个答案:

答案 0 :(得分:2)

你的算法坏了,我可以证明原因。如果有可能以这种方式填充数独谜题,以这种方式解决数独谜题也是微不足道的,但事实并非如此。

基本上,您的代码归结为以下内容。我已经在内部for循环中添加了早期退出,以便在我们找到当前行或列中已有的数字后停止搜索(并且实际上了解了99.9%的世界所关注的&#34;行&# 34;和&#34;列&#34;在NxN矩阵中):

 <md-toast style="height:100px;">

随着循环的进行,我们会报告我们正在尝试的号码,以及放置守门员时矩阵的样子。例如,上面的测试运行最初可能如下所示:

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

#define NSIZE 9

void print_matrix(int const ar[][NSIZE])
{
    for (size_t i=0; i<NSIZE; ++i)
    {
        for (size_t j=0; j<NSIZE; ++j)
        {
            fputc('0' + ar[i][j], stdout);
            fputc(' ', stdout);
        }
        fputc('\n', stdout);
    }
}

int main()
{
    srand((unsigned)time(NULL));
    int sudo[NSIZE][NSIZE] = enter image description here;
    int row, col;

    for(row=0;row<NSIZE;++row)
    {
        for(col=0;col<NSIZE;++col)
        {
            int row2 = 0, col2 = 0, num;
            printf("Trying ");
            do
            {
                num = rand()%9+1;
                printf("%d ", num);
                for(row2=0; row2<NSIZE && num!=sudo[row2][col]; ++row2);
                for(col2=0; col2<NSIZE && num!=sudo[row][col2]; ++col2);
            }
            while (row2 < NSIZE || col2 < NSIZE);
            fputc('\n', stdout);

            sudo[row][col] = num;
            printf("sudo[%d][%d] = %d\n", row, col, num);
            print_matrix(sudo);
        }
    }
}

这可能会持续一段时间。但最终,除非你得到非常幸运,否则必然会发生以下情况(这一轮在车轮脱落之前已经很深了):

Trying 8 
sudo[0][0] = 8
8 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 1 
sudo[0][1] = 1
8 1 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 9 
sudo[0][2] = 9
8 1 9 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 6 
sudo[0][3] = 6
8 1 9 6 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 3 
sudo[0][4] = 3
8 1 9 6 3 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 4 
sudo[0][5] = 4
8 1 9 6 3 4 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 4 6 7 
sudo[0][6] = 7
8 1 9 6 3 4 7 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
Trying 1 3 1 3 4 1 3 8 4 9 3 8 1 4 7 9 3 8 8 8 4 9 6 5 
sudo[0][7] = 5
8 1 9 6 3 4 7 5 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 

请注意,我们即将尝试填充Trying 1 6 3 4 sudo[6][6] = 4 8 1 9 6 3 4 7 5 2 1 3 5 4 8 6 2 7 9 3 6 4 8 7 9 5 2 1 7 9 1 2 4 5 3 8 6 4 7 3 9 2 8 6 1 5 5 4 2 3 6 1 8 9 7 6 8 7 1 9 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 。为此,我们必须找到一个不在sudo[6][7]列中的数字,也不是sudo[r][7]行。但是看看那些位置已有的数字。

sudo[6][c]

因此,我们正在寻找1:9中不在sudo[r][7] : {5,7,2,8,1,9} sudo[6][c] : {6,8,7,1,9,3,4} 的数字,我们永远不会找到它。

算法被破坏了。回溯用于这样的任务是有原因的。