2012-04-15 12 views
0

Ich bin dabei, einen Sudoku-Solver zu schreiben (muss noch den Boxcheck schreiben und vervollständige das Programm), aber ich teste es so, wie ich weiß. Das Rätsel, das ich gerade teste, ist "sehr einfach", da es in jeder Zeile/Spalte nur eine leere Zelle gibt. Das Puzzle beginnt mit "leeren" Zellen als Nullen. Mein Problem ist, dass, wenn ich das Programm starte und das Puzzle nach dem Aufruf von solve() ausgibt, die Nullen sich nicht ändern und das ursprüngliche Puzzle einfach ausgedruckt wird. Nicht sicher, was mein Problem ist, würde eine Richtung schätzen!Java Sudoku Solver nicht leere Zellen ändern

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

Nur ein Zeiger. Wenn Sie jede Spalte nach 'if (Grid [a] [0] == possible.get (a))' überprüfen, warum müssen Sie verschachtelte Schleifen verwenden? Sie können es einfach mit einer Schleife von "a = 0" bis "a = N" machen. Gleiches mit der Spaltenüberprüfung. – noMAD

Antwort

1

Schauen Sie sich Ihre Zeile if(Grid[a][0]==possible.get(a)) (und ähnliche Spots). Was macht es dort und was willst du eigentlich?

Ihre möglichen Array etwas wie folgt aussieht: [1,2,3,4,5,6,7,8,9]

und das Raster (nur die erste Zeile, da Sie nur die Überprüfung Grid [a] []) wie folgt aussehen könnte: [3,7,8,1,2,9,5,0,4]

Ihre Schleife wird individuell an jedem Element schrittweise suchen und zu sehen, ob sie gleich sind, dann wie folgt aus:

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

... etc

So, wie Sie sehen können, wenn Sie tun, um Ihre

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

Ihre möglichen Array immer noch voll von Optionen die meiste Zeit sein wird, es sei denn, Ihre erste Reihe sein geschieht einige Variationen über mit einer 0 in einem der Räume ... so wird der Count definitiv> 1 sein

Also wird Ihre nächste Schleife (for(l=0; l<9; l++)) als nächstes ausgeführt, so ist der Wert immer noch (wie Sie es initialisiert haben) 0.

Versuchen Sie, an diesen Punkten durch einen Debugger zu gehen und zu sehen, wie die Arrays interagieren.

0

Du bist gerade immer nur die erste Zeile und die erste Spalte und die Art und Weise Sie für die möglichen Zahlen überprüfen tut auch nicht das, was Sie wollen.

Ein paar Tipps zuerst:

Zunächst einmal ist es nicht notwendig, immer eine neue Variable für die Schleifen zu definieren, können Sie sie wiederverwenden können und dann haben Sie nicht zu viele von ihnen, und Sie gewonnen‘ Ich werde so leicht in ihnen verwirrt.

Zweitens, wenn Sie alle Variablen a, b, c, d usw. nennen, können Sie auch leicht verwirrt werden. Es ist zwar in Ordnung, Variablen in Schleifen als i, j zu benennen, aber wenn Sie zu viele Schleifen haben, ist es vielleicht besser, an bessere Namen zu denken. In diesem Fall zum Beispiel Zeile und Spalte.

Warum entfernen Sie die Nummern nicht aus der Liste? Etwas wie:

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

Dann wäre es einfacher, zu bestimmen, wie viele Werte, die Sie noch verlassen haben. Sie können einfach tun:

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

Und eine letzte Anmerkung, die Konvention für Variablennamen zu gehorchen, sollten Sie wahrscheinlich statt Grid verwenden Raster.

Und nun der Code:

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: die ganze Antwort in eine bessere Form neu geschrieben.

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

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

In diesen Zeilen verwenden Sie nicht b oder c. Sie wollen wahrscheinlich:

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

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

Auch die Grid[i][j]=value Prüfung innerhalb des if-Block sein sollte.

Sie könnten einen Set für die möglichen Werte anstelle von ArrayList verwenden.