2016-05-15 7 views
1

Ein Freund gab mir eine Klasse, die versucht, Sudoku Puzzles zu lösen. Thing ist, dass die Änderungen des Arrays innerhalb der Methode nicht im ursprünglichen Array widergespiegelt werden. Hier ist der Code:Verwalten von Referenzen in Parameterübergabe in Java

public static void solve(int array[][], int row, int col) 
    { 
     if(row > 8) 
     { 
      printBoard(array); // this gives the correct result 
      return; 
     } 
     if(array[row][col] != 0) 
      nextEmptyCell(array, row, col); 
     else 
     { 
      for(int num = 1; num < 10; num++) 
      { 
       if(validityRowColBox(array, row, col, num)) 
       { 
        array[row][col] = num; 
        nextEmptyCell(array, row, col); 
       } 
      } 
      array[row][col] = 0; 
     } 
    } 

    public static void nextEmptyCell(int array[][], int row, int col) 
    { 
     if(col < 8) 
      solve(array, row, col + 1); 
     else 
      solve(array, row + 1, 0); 
    } 

    //This boolean methods will checks the validity of the number for the given row, columns and its designated box. 
    public static boolean validityRowColBox(int array[][], int row, int col, int num) 
    { 
     for(int c = 0; c <9; c++) 
     { 
      if(array[row][c] == num) 
       return false;// It return false if the number is already exist in the given row. 
     } 
     for(int r = 0; r <9; r++) 
     { 
      if(array[r][col] == num) 
       return false;// It return false if the number is already exist in the given columns. 
     } 
     row = (row/3) * 3 ; 
     col = (col/3) * 3 ; 
     for(int r = 0; r < 3; r++) 
     { 
      for(int c = 0; c < 3; c++) 
      { 
       if(array[row+r][col+c] == num) 
        return false;// It return false if the number is already exist in the designated box. 
      } 
     } 
     return true;// Otherwise true. 
    } 

    // sample input 
    public static int[][] easy() 
    { 
     return new int[][] 
       {{0,0,0,2,6,0,7,0,1}, 
      {6,8,0,0,7,0,0,9,0}, 
      {1,9,0,0,0,4,5,0,0}, 
      {8,2,0,1,0,0,0,4,0}, 
      {0,0,4,6,0,2,9,0,0}, 
      {0,5,0,0,0,3,0,2,8}, 
      {0,0,9,3,0,0,0,7,4}, 
      {0,4,0,0,5,0,0,3,6}, 
      {7,0,3,0,1,8,0,0,0}}; 
    } 

    public static void main(String args[]) 
    { 
     int inputArray[][] = easy(); 
     solve(inputArray,0,0); 
     printBoard(inputArray); // items still the same! 
    } 
} 

Wenn ich das printBoard (Array) aufrufen; Funktion innerhalb der Methode scheinen sich die Elemente des Arrays zu ändern. Aber wenn ich das printBoard (Array) anrufe; Methode in der Hauptmethode auf dem ursprünglichen Array, sind die Änderungen verloren, die Werte sind wieder auf das Original zurück. Ich bin sehr verwirrt. Keine der Methoden erstellt ein neues Objekt und sollte daher immer auf das inputArray-Objekt verweisen. Was ist los?

Edit: Hier ist die Printplatte() -Methode

public static void printBoard(int array[][]) 
{ 
    //This is the board method. 
    for (int row = 0; row < array.length; row++) 
    { 
     if (row % 3 == 0)//If the row is divisible by 3 then print the plus(+) and minus(-) sign. 
      System.out.println("+-------+-------+-------+"); 
     for (int col = 0; col < array[row].length; col++) { 
      if (col % 3 == 0)// If the column is divisible by 3 then print the or(|) symbol. 
       System.out.print("| "); 

      System.out.print(array[row][col]+ " "); 
     } 
     System.out.println("|"); 
    } 
    System.out.println("+-------+-------+-------+"); 
} 
+1

wir im 'printBoard' Methode aussehen können? – Berger

+0

@Berger siehe Bearbeiten – morbidCode

Antwort

1

Das Problem ist, dass, wenn Sie aus den verschiedenen rekursiven Aufrufen wieder gibt es einen Befehl, der den Inhalt des Arrays (siehe Kommentare) ändern:

for(int num = 1; num < 10; num++) 
{ 
    if(validityRowColBox(array, row, col, num)) 
    { 
     array[row][col] = num; 
     nextEmptyCell(array, row, col); // after you finish you come back from here 
    } 
} 
array[row][col] = 0; // ...and this will change the solution you found 

Offenbar verursacht dies das Array in seinen ursprünglichen Zustand zurückzukehren.

Ich sah nicht, wie das Programm funktioniert, aber zu vermeiden, dass die Anweisung auszuführen, wenn wir die Lösung wird wieder die richtige Array, zum Beispiel gefunden:

public static boolean solve(int array[][], int row, int col) { 
    if (row > 8) { 
     printBoard(array); 
     return true; 
    } 
    if (array[row][col] != 0) { 
     return nextEmptyCell(array, row, col); 
    } 

    for (int num = 1; num < 10; num++) { 
     if (validityRowColBox(array, row, col, num)) { 
      array[row][col] = num; 
      if (nextEmptyCell(array, row, col)) { 
       return true;   // if solution is found we just exit 
      } 
     } 
    } 

    array[row][col] = 0; 

    return false; 
} 

public static boolean nextEmptyCell(int array[][], int row, int col) { 
    if (col < 8) { 
     return solve(array, row, col + 1); 
    } 
    return solve(array, row + 1, 0); 
}