为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]

Posted

技术标签:

【中文标题】为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]【英文标题】:Why is my JAVA code for solving sudoku using backtracking not giving any solution? [closed]为什么我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭] 【发布时间】:2020-01-10 21:49:55 【问题描述】:

这是 JAVA 中的代码,用于使用回溯解决任何 9*9 数独网格的数独问题。它不打印任何输出。我无法找到其中的错误。请帮忙。我已经以 9*9 网格的形式将示例输入之一包含在主函数中。 is_safe 函数,如果通过检查同一行、同一列和相应的 3*3 网格将所选字符放在那里是安全的。基本情况检查当 cr 变为 9 时,即到达棋盘的末端,而 cl 变为 0,即当我们伸出棋盘时。那么可能已经找到了可能的解决方案。我们此时打印板并返回调用函数。这似乎在逻辑上是正确的,但它没有打印任何输出。

    public static boolean is_safe(int mat[][],int cr,int cl,int i)
    
        for(int k=0;k<mat.length;k++)
        
            if(k!=cl&&mat[cr][k]==i)
            return false;
            if(k!=cr&&mat[k][cl]==i)
            return false;
        
        int row=cr-cr%3;
        int col=cl-cl%3;
        for(int k=0;k<3;k++)
        
            for(int l=0;l<3;l++)
            
                if(mat[k+row][l+col]==i)
                return false;
            
        
        return true;
    
    public static void print(int mat[][])
    
        for(int i=0;i<mat.length;i++)
        
            for(int j=0;j<mat[0].length;j++)
            
                System.out.println(mat[i][j]);
            
            System.out.println();
        
    
    public static void func(int mat[][],int cr,int cl)
    
        if(cr==mat.length&&cl==0)
        
            print(mat);
            return;
        
        int i=cr,j=cl;
        if(mat[cr][cl]!=0)
        
            if(cl+1==9)
            func(mat,cr+1,0);
            else
            func(mat,cr,cl+1);
        
        else
        for(int k=1;k<=9;k++)
        
            if(is_safe(mat,i,j,k))
            
                mat[i][j]=k;
                if(j+1==mat.length)
                func(mat,i+1,0);
                else
                func(mat, i, j+1);
                mat[i][j]=0;
            
        
    
    
    public static void main(String[] args) 
        int mat[][]=3,0,6,5,0,8,4,0,0,
                     5,2,0,0,0,0,0,0,0,
                     0,8,7,0,0,0,0,3,1,
                     0,0,3,0,1,0,0,8,0,
                     9,0,0,8,6,3,0,1,5,
                     0,5,0,0,9,0,6,0,0,
                     1,3,0,0,0,0,2,5,0,
                     0,0,0,0,0,0,0,7,4,
                     0,0,5,2,0,6,3,0,0;
        func(mat,0,0);
    
```



【问题讨论】:

请edit 提出问题并添加minimal reproducible example,并提供示例输入、预期和观察到的输出。 您应该只使用带断点的调试来检查代码流,以及与您希望它结束​​的位置相比,它当前的结束位置。 欢迎来到 SO!尽管这里的风格有问题(变量名、运算符之间的空格等),但这段代码在逻辑上是好的。问题是数独网格是无法解决的。将其与来自this site 的矩阵进行比较,您会发现9,0,0,8,6,3,0,1,5 应该是9,0,0,8,6,3,0,0,5。投票结束,因为不再可重现。 【参考方案1】:

永远不会调用您的打印方法!看来数独解不开了!

使用以下输入,您的代码可以正常工作:

3,0,6,5,0,8,4,0,0,
5,2,0,0,0,0,0,0,0,
0,8,7,0,0,0,0,3,1,
0,0,3,0,1,0,0,8,0,
9,0,0,8,6,3,0,0,5,
0,5,0,0,9,0,6,0,0,
1,3,0,0,0,0,2,5,0,
0,0,0,0,0,0,0,7,4,
0,0,5,2,0,6,3,0,0;

您还可以更改打印方法以使其更具可读性:

public static void print(int mat[][]) 
    for (int i = 0; i < mat.length; i++) 
        List<String> stringList = Arrays.stream(mat[i])
                .mapToObj(String::valueOf).collect(Collectors.toList());
        System.out.println(String.join(" ", stringList));
    

输出:

3 1 6 5 7 8 4 9 2
5 2 9 1 3 4 7 6 8
4 8 7 6 2 9 5 3 1
2 6 3 4 1 5 9 8 7
9 7 4 8 6 3 1 2 5
8 5 1 7 9 2 6 4 3
1 3 8 9 4 7 2 5 6
6 9 2 3 5 1 8 7 4
7 4 5 2 8 6 3 1 9

【讨论】:

以上是关于为啥我使用回溯解决数独的 JAVA 代码没有给出任何解决方案? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

求解数独的回溯算法

求解数独的所有解法,java编程实现

数独1--暴力回溯法(时间超)

数独回溯 无效数独

数独 算法 C语言 代码

靶型数独