This链接具有Sudoku Solver算法的Backtracking实现。注意如果最初分配的值没有给出有效输出,行号42如何将最初分配给单元格的值恢复为另一个值。
但是,我不明白仅仅改变那个细胞的价值就足够了。这个调用可以触发许多其他调用,而因为数组(矩阵)由内存(引用)传递,它不保留矩阵的副本(grid [N] [N] )在递归函数的每次调用时,所以更改直到递归的基本情况,即使在递归的第一个递归帧中也会反映出来。
据我所知,在调用递归函数之前,你应该制作一个grid [N] [N]的临时副本,并在调用返回后立即恢复,并在调用同一帧中的下一个函数之前恢复它
像
这样的东西for (int num = 1; num <= N; num++)
{
// if looks promising
if (isSafe(grid, row, col, num))
{
//save grid state
int[][] temp = new int[N][N];
save(temp,grid); //copy all values from grid to temp
// make tentative assignment
grid[row][col] = num;
// return, if success, yay!
if (SolveSudoku(grid))
return true;
//restore grid state
restore(temp,grid); //copy all values from temp back to grid
// failure, unmake & try again
grid[row][col] = UNASSIGNED;
}
}
请帮助我理解这个细节。
答案 0 :(得分:3)
保存状态:每次递归调用都会在调用堆栈中保存状态。
修改网格的未分配部分,直到找到有效的解决方案。一旦完成,所有堆叠的函数调用都将终止(第38和39行),使grid[][]
处于解决状态。如果不是,则将当前单元格恢复为其UNASSIGNED
值并尝试下一个可能的值。
这是一个蛮力解算器。您可能也想围绕它进行谷歌搜索。
希望这有帮助。