Java 很难理解递归如何与这个数独解算器一起工作
我已经研究这段代码好几个小时了,我不知道它是如何工作的。有人能详细解释一下递归是如何使用这些函数的吗?请记住,我对编程非常陌生 最让我困惑的是solve()是如何被反复调用的?当它到达拼图[row][col]=0时,它不会停止吗 顺便说一下,这是工作代码 编辑:谢谢你的回答!但我看不出它在哪里回溯Java 很难理解递归如何与这个数独解算器一起工作,java,recursion,sudoku,Java,Recursion,Sudoku,我已经研究这段代码好几个小时了,我不知道它是如何工作的。有人能详细解释一下递归是如何使用这些函数的吗?请记住,我对编程非常陌生 最让我困惑的是solve()是如何被反复调用的?当它到达拼图[row][col]=0时,它不会停止吗 顺便说一下,这是工作代码 编辑:谢谢你的回答!但我看不出它在哪里回溯 void solve(int row, int col) throws Exception { if(row > 8) { throw new Exception
void solve(int row, int col) throws Exception
{
if(row > 8)
{
throw new Exception( "Solution found" ) ;
}
if(puzzle[row][col] != 0)
{
next(row, col);
}
else
{
for( int num = 1; num < 10; num++ )
{
if( checkHorizontal(row,num) && checkVertical(col,num) && checkBox(row,col,num) )
{
puzzle[row][col] = num ;
next( row, col ) ;
}
}
puzzle[row][col] = 0 ;
}
}
public void next( int row, int col ) throws Exception
{
if( col < 8 )
{
solve(row, col + 1) ;
}
else
{
solve(row + 1, 0) ;
}
}
void solve(int行,int列)引发异常
{
如果(第8行)
{
抛出新异常(“找到解决方案”);
}
如果(拼图[行][列]!=0)
{
下一行(行、列);
}
其他的
{
对于(int num=1;num<10;num++)
{
if(选中水平(行,数值)和选中垂直(列,数值)和复选框(行,列,数值))
{
拼图[行][col]=num;
下一行(行、列);
}
}
拼图[行][col]=0;
}
}
public void next(int行,int列)引发异常
{
if(col<8)
{
求解(行,列+1);
}
其他的
{
求解(行+1,0);
}
}
下一个函数可以描述为查找第一个自由字段并从该字段开始求解过程的函数
然后,实际的递归是一个简单的回溯()。一般方案可能更容易掌握一些伪代码:
Solution findSolution(Board board) {
if (board.isSolved()) return solutionFor(board);
// An "action" here refers to placing any number
// on any free field
for (each possible action) {
do the action // That is: place a number on a free field
// The recursion:
Solution solution = findSolution(board);
if (solution != null) return solution;
// No solution found
UNdo the action // That is: remove the number from the field
// Now the loop continues, and tries the
// next action...
}
// Tried all possible actions, none did lead to a solution
return null;
}
通常,可以使用两个嵌套的for循环来确定这些“操作”:
for (each free field f)
{
for (each number n in 1..9)
{
place 'n' on 'f'
try to find solution
remove 'n' from 'f'
}
}
在这种情况下,外部循环在next
函数中有些“隐藏”
在这种情况下,对于数独来说,这种回溯的特殊实现可能不会很好地工作。可能需要几万亿年才能找到解决方案,因为有太多的可能性。但这基本上取决于check*
方法的“聪明”程度。快速检测(部分)解决方案已经无效的情况非常重要。也就是说,你是否有一种无论如何都找不到解决办法的情况。例如,当一个3x3平方格的两个单元格包含相同的数字时,情况已经“无效”。例如,可以通过显式存储仍然可用的数字来避免这种情况,但是代码当然会变得更复杂