我正在使用数独求解器,当我的程序耗尽其输出时,我的程序无法向后递归。
我有四个功能来检查:
scolumn
,srow
,sbox
。如果数字已分别存在于列行或框中,则每个都将返回false。
bool sudoku::solve(int row, int column)
{
if(column == 9)
{
column = 0;
row +=1;
}
if(puzzle[row][column] != 0)
{
solve(row, column + 1);
return false;
}
else
{
for(int n = 0; n < 10; n ++)
{
if(srow(column, n) && scolumn(row,n) && sbox(row, column, n)
{
puzzle[row][column] = n;
if(!solve(row, column + 1);
table[row][column] = 0;
}
}
puzzle[row][column] = 0;// if not commented out then infinite loop
}
return false
}
问题在于,如果它在9处并且没有下一个选择,它将不会正确回溯。
答案 0 :(得分:1)
您的代码存在许多问题,正如人们在评论中所观察到的那样。
这个答案总结了其中一些:
1)As @ n.m。说,你不应该尝试'0'作为单元格中的有效选择。毫无疑问,这将是一些无限循环的原因。
2)正如您所观察到的,您不知道递归是如何完成的。答案是,当你到达最后一个单元格,并且找到一个适用于它的值时,你应该返回true。这就是应该打破for(n)循环:该循环说“尝试每个数字直到调用此单元格右侧的成功”。成功是通过你的例程返回真实来衡量的。
由于您尝试了当前单元格中的每个数字(n),无论对其右侧的求解是否有效......都无法正常工作。
你会知道在以下情况下你的问题更加正确:
当您发现可以在最后一个单元格中放置一个数字时,您可以在代码中看到返回true的位置(9,9)
当右边的调用成功时,您可以看到停止尝试数字(n = 0..9)的方式。
答案 1 :(得分:0)
给定int puzzle[9][9]
以及您的srow
,scol
和sbox
函数:
bool sudoku::solve(int row, int column) //to solve entire puzzle, call with parameters 0 and 0
{
int cell;
//ignore all nonzero cells (zero = empty)
while (row < 9 && puzzle[row][column] != 0)
{
column++;
if (column == 9)
{
row++;
column = 0;
}
}
if (row == 9) return true; //puzzle is already solved
//try values 1-9 inclusive. If successful, then return true
for (cell = 1; cell <= 9; cell++)
{
puzzle[row][column] = cell;
if (srow(row) &&
scol(column) &&
sbox(row-row%3, column-column%3) &&
solve(row, column)) //recursion!!
{
return true;
}
}
//if no value works, reset the cell and return false.
puzzle[row][column] = 0;
return false;
}