2012-04-15 4 views
0

私はsudokuソルバを書く途中です(まだボックスチェックを書いて実際にプログラムを完成させる必要があります)。私が今テストしているパズルは、どの行/列にも空のセルが1つしかないので、非常に簡単です。パズルは "空の"セルでゼロから始まります。私の問題は、プログラムを実行してsolve()が呼び出された後にパズルを印刷すると、ゼロは変更されず、元のパズルはただ印刷されるということです。私の問題が何であるかわからない、ある方向に感謝するだろう!Javaのsudokuソルバが空のセルを変更していない

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; 
      } 
     } 
    } 
} 
+0

ポインタだけです。 'if(Grid [a] [0] == possible.get(a))'のためにすべての列をチェックしているとき、なぜネストされたループを使う必要がありますか? 'a = 0'から' a = N'までの1つのループでこれを行うことができます。列のチェックと同じです。 – noMAD

答えて

1

if(Grid[a][0]==possible.get(a))(同様のスポット)をご覧ください。それはあなたが実際に何を望んでいるのか対何ですか?

あなたの可能性配列は、このようなものになります。[1,2,3,4,5,6,7,8,9]

とグリッド(ちょうど最初の行を、あなただけのグリッドをチェックしているので、[A] [])のようになります。 [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 

...など

だから、あなたが見ることができるように、あなたが行うときに、あなたの

あなたの可能性アレイが依然としてほとんどの時間は、あなたの最初の行があることを起こる場合を除きオプションの完全であることを行っている
for(k=0; k<9; k++){ 
    if(possible.get(k)!=0){ 
     count++; 
    } 
} 

[1,2,3,4,5,6,7,8,9]のいくつかのバリエーションが空白の1つに0を持っていますので、カウントは確実に> 1になります。

次のループ(for(l=0; l<9; l++))が次に実行されるため、値はまだ初期化されています0.

これらのポイントでデバッガをステップ実行し、アレイがどのように相互作用しているかを確認します。

0

あなたは常に最初の行と最初の列のみをチェックしています。また、可能な数字を確認する方法も、あなたが望んでいないものです。最初

いくつかのヒント:「すべての

まず、あなたがそれらを再利用することができ、その後、あなたがそれらのあまりにも多くを持っていないだろう、いつものループのための新しい変数を定義する必要はありません、あなたが勝ちましたそれほど混乱しないでください。

第2に、すべての変数にa、b、c、dなどの名前を付けると、簡単に混乱することもあります。ループ内の変数の名前をi、jとしても構いませんが、ループが多すぎる場合は、より良い名前を考える方が良いかもしれません。この場合、たとえば行と列。

なぜ可能なリストから数字を削除しないのですか?次のようなものがあります。

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

次に、残っている値の数を判断することは簡単です。

最後に、変数名の規則に従うには、Gridの代わりにgridを使用するのがよいでしょう。

そして今コード:

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; 
      } 
     } 
    } 
} 

EDIT:より良い形に全体の答えを書き直しました。

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チェックがあればブロック内にある必要があります。

ArrayListではなく、可能な値としてSetを使用します。

関連する問題