C中的数独解算器。程序在某些情况下停止,我不';我不知道为什么
我正在为一个解决数独难题的类编写一个c语言程序。我们应该实现三种方法,首先在只有一个可能选择的每个正方形中放置正确的数字,重复直到找不到为止。接下来,它使用蛮力,在每个正方形中放置尽可能少的数字。我有这两种方法。最后一种方法是带回溯的蛮力,这是蛮力函数的一部分。它的工作原理与普通蛮力相同,不同的是,它到达一个不能在其中放置数字的正方形时,移动到前一个正方形并放置下一个最高的数字。一旦这是实施这应该解决所有给定的数独难题,但这是我有麻烦的地方 我已经实现了所有这三种方法,并且给我们提供了不同的数独难题示例,一些可以只使用第一种“单选”方法解决,一些可以只使用“单选”和“不回溯的蛮力”解决,还有一些使用“单选”和“带回溯的蛮力”解决。我的程序既可以处理“单选”难题,也可以处理“单选”和“没有回溯的暴力”难题。然而,它不适用于“单一选择”和“回溯暴力”难题 奇怪的是,我不明白,对于回溯谜题,程序甚至在调用蛮力函数之前就停止工作了 以下是我的主要功能:C中的数独解算器。程序在某些情况下停止,我不';我不知道为什么,c,sudoku,backtracking,solver,C,Sudoku,Backtracking,Solver,我正在为一个解决数独难题的类编写一个c语言程序。我们应该实现三种方法,首先在只有一个可能选择的每个正方形中放置正确的数字,重复直到找不到为止。接下来,它使用蛮力,在每个正方形中放置尽可能少的数字。我有这两种方法。最后一种方法是带回溯的蛮力,这是蛮力函数的一部分。它的工作原理与普通蛮力相同,不同的是,它到达一个不能在其中放置数字的正方形时,移动到前一个正方形并放置下一个最高的数字。一旦这是实施这应该解决所有给定的数独难题,但这是我有麻烦的地方 我已经实现了所有这三种方法,并且给我们提供了不同的数独
#include <stdio.h>
#include "sudokusolver.h"
int main()
{
int puzzle[9][9], i, j, count, attempts=0, backTracks=0;
readSudoku(puzzle);
printf("a\n");
do
{
count=0;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(singleCandidate(puzzle, i, j)==1)
count++;
}
}
}while(count!=0);
bruteForce(puzzle, &attempts, &backTracks);
printSudoku(puzzle);
return 0;
}
这里有一个输出不起作用的例子。这是一个必须使用“单选”和“回溯暴力”解决的示例难题:
程序继续运行,就好像它在一个无限循环中,^C代表我退出程序一样。正如你所看到的,这个程序甚至从来没有到达它在数独游戏中读取的正下方的printf(“a”),甚至在它调用“带回溯的蛮力”函数之前,这很奇怪,因为只有那些需要带回溯的蛮力的游戏才不起作用
下面是readSudoku函数,它似乎被卡住了:
void readSudoku(int puzzle[][9])
{
int i, j;
for(i=0;i<9;i++)
{
printf("Enter line %d: ", i+1);
for(j=0;j<9;j++)
{
scanf("%1d", &puzzle[i][j]);
}
}
}
void readSudoku(int-puzzle[][9])
{
int i,j;
对于(i=0;i我猜问题可能出在singleCandidate()
中。我看不到它的源代码,但您应该验证它在不改变谜题时不返回1,因为这会导致无休止的循环
同时检查当您获得无效输入时(即数独没有解决方案时)它的行为。在您的bruteForce
中,您有
/* No legal guess found, so backtrack */
while(puzzle[i][j]==0)
{
/* Find previous guessed position */
/* the last guess was as puzzle[i][j] */
temp=puzzle[i][j]+1;
for(k=temp;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
found=1;
puzzle[i][j]=k+1;
break;
}
}
if(found==0)
puzzle[i][j]=0;
}
然后访问谜题[-1][-1]
,调用未定义的行为
如果不幸的是,无效的内存访问没有导致崩溃(看起来是这样的),那么可能是checkValid(-1,-1,k+1)
对某些k
返回1
,然后您开始再次尝试解决这个难题,进入相同的循环
不可否认的是,<代码> PROTF(“A\N”);应该打印出<代码> A <代码>,如果终端被设置为正常缓冲模式,但我认为打印缓冲区不可能比“<代码> > ReSudiukU/CODE >更神奇地检测需要回溯并拒绝对它们进行处理的谜题。(可能是“a”已缓冲,因此不显示。请在
printf
之后尝试fflush(stdout);
)@missingno:你不应该编辑标记…@HotLicks这不太可能,因为stdout是用每一个换行符刷新的,但这仍然是一件值得尝试的事情。问题不是添加标记是错误的…但是添加应该来自OP…我被告知…在调试器中运行程序,并逐步完成代码一然后你可以检查变量,检查循环中的条件等等。
void readSudoku(int puzzle[][9])
{
int i, j;
for(i=0;i<9;i++)
{
printf("Enter line %d: ", i+1);
for(j=0;j<9;j++)
{
scanf("%1d", &puzzle[i][j]);
}
}
}
void bruteForce(int puzzle[][9], int *attempt, int *backtracks)
{
int stable[9][9], i, j, k, found=0, temp=0;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(puzzle[i][j]==0)
stable[i][j]=0;
else
stable[i][j]=1;
}
}
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
for(k=0;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
puzzle[i][j]=k+1;
break;
}
if(k==8)
break;
}
while(puzzle[i][j]==0)
{
found=0;
temp=j-1;
for(j=temp;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
temp=i-1;
if(found==0)
{
for(i=temp;i>=0;i--)
{
for(j=8;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
if(found==1)
break;
}
}
found=0;
temp=puzzle[i][j]+1;
for(k=temp;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
found=1;
puzzle[i][j]=k+1;
break;
}
}
if(found==0)
puzzle[i][j]=0;
}
}
}
}
/* No legal guess found, so backtrack */
while(puzzle[i][j]==0)
{
/* Find previous guessed position */
/* the last guess was as puzzle[i][j] */
temp=puzzle[i][j]+1;
for(k=temp;k<9;k++)
{
if(checkValid(puzzle, i, j, k+1)==1)
{
found=1;
puzzle[i][j]=k+1;
break;
}
}
if(found==0)
puzzle[i][j]=0;
}
found=0;
temp=j-1;
for(j=temp;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
// Here, j == -1
temp=i-1;
if(found==0)
{
// if i == 0
for(i=temp;i>=0;i--)
{
// i is set to -1 and the loop ends right now, with i == -1 and j == -1
// if i was > 0, j is decremented from 8 to -1 for all i down to 0 in the inner loop
for(j=8;j>=0;j--)
{
if(stable[i][j]==0)
{
found=1;
break;
}
}
if(found==1)
break;
// i is finally set to -1, with j still -1
}
}
found=0;
temp=puzzle[i][j]+1;