0

我正在编写数独求解器(仍然需要编写复选框并实际完成程序)但我正在测试它,因为我知道。我现在正在测试的谜题“非常简单”,因为任何行/列中只有一个空单元格。这个谜题以“空”单元格作为零开始。我的问题是,当我运行程序并在调用 solve() 后打印出拼图时,零并没有改变,原始拼图只是打印出来。不知道我的问题是什么,希望得到一些指导!

public ArrayList<Integer> create(){

    ArrayList<Integer> possible = new ArrayList<Integer>(); 

    for(int i=1; i<10; i++){
        possible.add(i);
    }
    return possible;
}
public sudoku( int size )
{
    SIZE = size;
    N = size*size;

    Grid = new int[N][N];
    for( int i = 0; i < N; i++ ) 
        for( int j = 0; j < N; j++ ) 
            Grid[i][j] = 0;
}

public void solve()
{ 
    int a, b, c, d, i, j, k, l; 

    int count = 0;
    int value= 0;

    for(i=0; i<N;i++){
        for(j=0; j<N;j++){  
            if(Grid[i][j]==0){

                ArrayList<Integer> possible = create();

                //check row             
                for(a=0; a<N;a++){
                    for(b=0; b<N; b++){  
                        if(Grid[a][0]==possible.get(a)){
                            possible.set(a, 0);
                        }
                    }
                }
                //check column
                for(c=0; c<N;c++){
                    for(d=0; d<N;d++){  
                        if(Grid[0][d]==possible.get(d)){
                            possible.set(d,0);
                        }
                    }
                }
                for(k=0; k<9; k++){
                    if(possible.get(k)!=0){
                        count++;
                    }
                }
                if(count==1){
                    for(l=0; l<9; l++){
                        if(possible.get(l)!=0){
                            value=possible.get(l);
                        }
                    }
                }
                Grid[i][j]=value;
            }
        }
    }
}
4

3 回答 3

1
if(Grid[a][0]==possible.get(a))

if(Grid[0][d]==possible.get(d))

您不要在这些行中使用 b 或 c 。你可能想要:

if(Grid[a][i]==possible.get(b))

if(Grid[j][d]==possible.get(c))

此外,Grid[i][j]=value检查应该在 if 块内。

您可能希望将 aSet用于可能的值,而不是ArrayList.

于 2012-04-15T14:59:30.943 回答
1

看看你的线if(Grid[a][0]==possible.get(a))(和类似的点)。它在那里做什么与你真正想要什么?

您可能的数组如下所示: [1,2,3,4,5,6,7,8,9]

并且您的网格(只是第一行,因为您只检查 Grid[a][ 0 ])可能看起来像这样: [3,7,8,1,2,9,5,0,4]

您的循环正在逐个查看每个元素并查看它们是否相等,如下所示:

if(1 == 3) ... it's not
if(2 == 7) ... it's not
if(3 == 8) ... it's not

... ETC

所以,正如你所看到的,当你做你的

for(k=0; k<9; k++){
    if(possible.get(k)!=0){
        count++;
    }
}

大多数情况下,您可能的数组仍然会充满选项,除非您的第一行恰好是其中[1,2,3,4,5,6,7,8,9]一个空格中的 0 的一些变化......所以 count 肯定会大于 1

因此,您的下一个循环 ( for(l=0; l<9; l++)) next 将被执行,因此值仍然(在您初始化时)为 0。

尝试在这些点上逐步通过调试器并查看数组如何交互。

于 2012-04-15T15:07:17.497 回答
0

您总是只检查第一行和第一列,而检查可能数字的方式也不是您想要的。

先说几个tips:

首先,没有必要总是为循环定义一个新变量,你可以重用它们,然后你不会有太多的循环,你也不会那么容易被它们弄糊涂。

其次,如果您将所有变量命名为 a、b、c、d 等,您也很容易混淆。虽然可以将循环中的变量命名为 i、j,但如果循环太多,最好考虑更好的名称。在这种情况下,例如行和列。

为什么不从可能的列表中删除数字?就像是:

int index = possible.indexOf(a);
if (index != -1) possible.remove(index);

然后更容易确定您还剩下多少值。你可以简单地做:

if (possible.size()==1) value = possible.get(0);

最后一点,要遵守变量名称的约定,您可能应该使用网格而不是网格。

现在代码:

public void solve() { 
    int row, column, i;
    int count = 0;
    int value= 0;
    int index = 0;

    for(row=0; row<N; row++){
        for(column=0; column<N; column++){  
            if(Grid[row][column]==0){

                ArrayList<Integer> possible = create();

                //check row             
                for(i=0; i<N; i++){
                    index = possible.indexOf(Grid[row][i]);
                    if (index != -1) possible.remove(index);
                }
                //check column
                for(i=0; i<N; i++){
                    index = possible.indexOf(Grid[i][column]);
                    if (index != -1) possible.remove(index);
                }

                if (possible.size()==1) value = possible.get(0);

                Grid[row][column]=value;
            }
        }
    }
}

编辑:将整个答案重写为更好的形式。

于 2012-04-15T14:58:00.167 回答