Java 求解数独程序

Java 求解数独程序,java,loops,sudoku,Java,Loops,Sudoku,我这里有个问题。我没有得到完美的输出。下面是我为准备数独而编写的代码。即使我知道它的原因,因为它无法创建任何新的唯一数字,它正在打印默认值0。我知道我缺少一些我想不起来的东西。有人能提出解决办法吗?提前谢谢 public class FinalSudoku { int a[][]=new int[9][9]; public void initialize1() { for(int i=0;i<9;i++) { fo

我这里有个问题。我没有得到完美的输出。下面是我为准备数独而编写的代码。即使我知道它的原因,因为它无法创建任何新的唯一数字,它正在打印默认值0。我知道我缺少一些我想不起来的东西。有人能提出解决办法吗?提前谢谢

public class FinalSudoku 
{
    int a[][]=new int[9][9];
    public void initialize1()
    {
        for(int i=0;i<9;i++)
        {
         for(int j=0;j<9;j++)
        {
             a[i][j]=0;
        }

     }
    }
    protected boolean detectRow( int row, int num )
       {
          for( int col = 0; col < 9; col++ )
             if( a[row][col] == num )
                return false;

          return true ;
       }

    protected boolean detectCol( int col, int num )
       {
          for( int row = 0; row < 9; row++ )
             if( a[row][col] == num )
                return false ;

          return true ;
       }

    protected boolean detectBox( int row, int col, int num )
       {
          row = (row / 3) * 3 ;
          col = (col / 3) * 3 ;

          for( int r = 0; r < 3; r++ )
             for( int c = 0; c < 3; c++ )
             if( a[row+r][col+c] == num )
                return false ;

          return true ;
       }

    public void solve( int row, int col ) throws Exception
    {
        if( row > 8 )
             throw new Exception( "Solution found" ) ;

        if( a[row][col] != 0 )
             next( row, col ) ;
          else
          {
    for( int num = 1; num < 10; num++ )
    {
       if(detectRow(row,num) && detectCol(col,num) && detectBox(row,col,num) )
       {
          a[row][col] = num ;
          next(row, col) ;
       }
    }
          }
    }
    public void display()
    { 
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
    }

    public void next( int row, int col ) throws Exception
       {
          if( col < 8 )
             solve( row, col + 1 ) ;
          else
             solve( row + 1, 0 ) ;
       }  
    public static void main(String[] args) throws Exception
    {
        FinalSudoku fs = new FinalSudoku();
        fs.initialize1();

        fs.solve(0,0);

        fs.display();
    }

}
公共课程最终课程
{
int a[][]=新int[9][9];
公共无效初始值1()
{

对于(int i=0;i你不是在写一个解算器,而是在写一个生成器。你的问题是你在填充值时,没有真正检查它们是否会阻塞这个谜题。看看你的算法停止的地方

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

2 1 4  3 6 5  8 9 7
3 6 7  2 9 8  1 4 5
5 9 8  0 0 0  0 0 0 < This row contains 5 and 8, 9

0 0 0  0 0 0  0 0 0
0 0 0  0 0 0  0 0 0
0 0 0  0 0 0  0 0 0
       ^
 This column contains 1,2,3,4 and 7

 And the center box, contains 6
123456789
4 5 6  7 8 9  3 2 1
7 8 9  1 2 3  4 5 6
2 1 4  3 6 5  8 9 7
3 6 7  2 9 8  1 4 5
5980000<这一行包含5和8,9
0 0 0  0 0 0  0 0 0
0 0 0  0 0 0  0 0 0
0 0 0  0 0 0  0 0 0
^
此列包含1、2、3、4和7
中间的盒子里有6个
所以所有的数字都是那个地方的


看看这里:
这段代码生成一个填充的网格,也许这是有趣的开始


感谢Alex D,他的观点很好:


如果你真的想使用暴力算法,就像你正在尝试做的那样,你需要让它备份,并在它到达无法成功的点时尝试不同的解决方案。如果它一直备份到开始,没有选择,那么就没有解决方案。有一些标准的方法来实现这一点“带回溯的递归搜索”


此求解算法可以工作,但需要一些递归知识。

此代码检查数独。如果正确,则检查\u Sudoku()方法返回true如果错误,则显示具有重复元素的行和列编号

  public static void main(String[] args) {
    int array[][]={{9,6,3,1,7,4,2,5,8},
                   {1,7,8,3,2,5,6,4,9},
                   {2,5,4,6,8,9,7,3,1},
                   {8,2,1,4,3,7,5,9,6},
                   {4,9,6,8,5,2,3,1,7},
                   {7,3,5,9,6,1,8,2,4},
                   {5,8,9,7,1,3,4,6,2},
                   {3,1,7,2,4,6,9,8,5},
                   {6,4,2,5,9,8,1,7,3}};

    Sudoku sudoku=new Sudoku();
    if(sudoku.check_sudoku(array))
    {
        System.out.println("You won the game :)");
    }


}


public class Sudoku {

private int temp1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, temp2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private int data1, data2;

public boolean check_sudoku(int array[][]) {
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            data1 = array[i][j];
            data2 = array[j][i];
            if (data1 >= 10 || data2 >=10 || data1 <= 0 || data2 <= 0) {
                System.out.println("Invalid Solution because value must be in between 1 to 9");
                return false;
            } else if (temp1[data1 - 1] == 0 || temp2[data2 - 1] == 0) {
                System.out.println("Invalid Solution please check " + (i + 1) + " row " + (j + 1) + " column or " + (j + 1) + " row " + (i + 1) + " column");
                return false;
            } else {
                temp1[data1 - 1] = 0;
                temp2[data2 - 1] = 0;
            }
        }
        int check1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int check2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        temp1 = check1;
        temp2 = check2;
    }
    return true;
}
publicstaticvoidmain(字符串[]args){
int数组[][]={{9,6,3,1,7,4,2,5,8},
{1,7,8,3,2,5,6,4,9},
{2,5,4,6,8,9,7,3,1},
{8,2,1,4,3,7,5,9,6},
{4,9,6,8,5,2,3,1,7},
{7,3,5,9,6,1,8,2,4},
{5,8,9,7,1,3,4,6,2},
{3,1,7,2,4,6,9,8,5},
{6,4,2,5,9,8,1,7,3}};
数独=新数独();
if(数独。检查_数独(数组))
{
System.out.println(“您赢得了比赛:)”;
}
}
公共级数独{
私有int temp1[]={1,2,3,4,5,6,7,8,9},temp2[]={1,2,3,4,5,6,7,8,9};
私有int数据1、数据2;
公共布尔检查数独(整数数组[][]){
对于(int i=0;i<9;i++){
对于(int j=0;j<9;j++){
data1=数组[i][j];
data2=数组[j][i];

如果(data1>=10 | | data2>=10 | | data1@AndyRay:row=(row/3)有什么问题*3
?解决数独问题是一个非常复杂的问题。生成一个问题更是如此。你似乎是一个新手程序员,你可能不具备解决这两个问题所需的数学技能。因此,你为什么不创建一个数独解验证程序。也就是说,编写一个程序,给定一个9x9的数字网格,检查它们遵循数独的规则。此外,异常用于异常行为。当目标是找到解决方案时,找到解决方案不是异常行为。@安德雷:不,安迪,一点也不……他在执行整数除法,这意味着你失去了除法的小数部分:
7/3==2
。然后再乘以它按3给出
6
。此方法用于向下取整到网格中方框的最低单元格。执行
(x/3)后*3
,值
0,1,2
给出结果
0
。值
3,4,5
给出
3
和值
6,7,8
给出
6
@AndyRay,但行是整数且
4/3*3=1*3!=4
。如果您确实想使用OP试图使用的暴力算法,您可以需要让它备份,并在到达无法成功的点时尝试不同的解决方案。如果它一直备份到开始,没有选择可以尝试,那么就没有解决方案。有几种标准方法可以实现这种“带回溯的递归搜索”@Martincourtaux,也许你想在你的答案中添加一些信息?如果是,我将删除此评论。感谢你的回复Martijn。我知道被阻止的原因,我在问题中提到了。但问题是,我想寻求帮助,是否有任何技术可以验证填写的数字并安排这些数字以当前数字获得值的方式进行BER。