递归回溯问题 - 数独求解示例

时间:2014-03-21 00:00:37

标签: java recursion

最近,我一直试图通过一些递归来更好地理解这个过程。虽然我理解基本的递归技术,但我仍然在努力解决递归回溯的问题。为了帮助解决这个问题,我尝试编写了一个方法,该方法在给定2D数组和两个整数r和c时解决了数独求解器,它们用于表示当前列和行。

我相信所有内容都已正确设置,但我无法弄清楚如何处理&#34;解开&#34;或者在我的初始方法调用到达最终基本情况后会发生什么。< / p>

到目前为止,当我运行这个方法时,它只返回一个空的板,(除非之前有一个值,在这种情况下它保持不变)。我觉得&#34;董事会[r] [c] = 0&#34;我在方法结束时可能与此有关。

方法&#34; digitsValid&#34;对应于一种方法,该方法检查以确保板上的当前位置是行,列和3x3子网格内的有效移动。

非常感谢任何帮助。

private boolean sudokuSolver(int[][] board, int r, int c) {

    if(c > 8) {
        c = 0;
        r = r + 1;
    }

    if(r > 8) {
        return true;
    }

    if(board[r][c] != 0) {
        sudokuSolver(board, r, c + 1);
    } else {
        for(int i = 1; i <= 9; i++) {
            if(digitsValid(board, r, c)) {
                board[r][c] = i;    
                if(sudokuSolver(board, r, c + 1)) {
                    return true;
                }
            }
        }
    }

    board[r][c] = 0;
    return false;
}

1 个答案:

答案 0 :(得分:2)

我认为你原来的评估是正确的。递归方法听起来令人困惑,但想到它们是这样的:

public class RecursiveTest{

public static void main(String[] args){
    int x = 5;
    recursiveMethod(x);
}


public static void recursiveMethod(int i){
    System.out.println("Method just started for i = " + i);
    if(i > 0)
        recursiveMethod(i - 1);
    System.out.println("Method just ended for i = " + i);
}
}

产生以下输出:

Method just started for i = 5
Method just started for i = 4
Method just started for i = 3
Method just started for i = 2
Method just started for i = 1
Method just started for i = 0
Method just ended for i = 0
Method just ended for i = 1
Method just ended for i = 2
Method just ended for i = 3
Method just ended for i = 4
Method just ended for i = 5

<强>解释

递归方法与其他任何方法都没有什么不同。它执行一些代码,在某些时候调用一个方法,运行该方法然后继续运行其余的代码并完成任何其他方法完成的地方。

唯一的区别是方法调用是对自身的调用。这就像你将同一个方法复制粘贴5次并将其命名为不同的东西然后将它们“菊花链”在一起一样。

在上面的示例中,原始值为5,它打印出它开始for i = 5,然后运行相同的方法,值为4.打印出来,然后运行3等等一旦到达最终值,其中i = 0,if语句失败,因此它停止了递归调用。我们当前所在的方法(i = 0)通过编写Method just ended for i = 0来完成,然后在i = 1时返回到调用方法,然后返回跟踪它进入的方式。

您的代码

我不太清楚你在这里发生了什么。你的例子有用吗?我希望看到isValid()方法,但您拥有以下代码:

for(int i = 1; i <= 9; i++) {   // Runs the following code 9 times.
    if(digitsValid(board, r, c)) {   // if true once, true every time
        board[r][c] = i;    
        if(sudokuSolver(board, r, c + 1)) {  // this is a totally separate method
            return true;
        }
    }
}

你的循环运行了9次。跟随它的if语句永远不会改变。其中的值不在循环内编辑,因此如果在i = 1时评估为true,那么它将在for循环的所有9次迭代中评估为true。这意味着board[r][c]的值将以9结束。

从它的外观来看,它将返回false的唯一方法是,在调用方法时数组中是否存在无效数字。