2015-04-20 50 views
1

我想立即用回溯編寫一個數獨求解器,我已經解決了一些問題,但是現在我不知道該怎麼做。在線程中的Java異常main java.lang.arrayIndexoutofboundsexception 9

這就是問題所在:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9 
at ISudoku.NumberOnBoard(ISudoku.java:19) 
at ISudokuSolver.containedinRoC(ISudokuSolver.java:23) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:10) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.backtracking(BacktrackingISudokuSolver.java:19) 
at BacktrackingISudokuSolver.solveSudoku(BacktrackingISudokuSolver.java:4) 
at Examples.main(Examples.java:17) 

當我運行代碼

我不指望能得到遞給了我正確的代碼,我只是欣賞每一個幫助。

public class ISudoku { 

    private boolean[][] sudokuboolean; 
    private int[][] sudokuboard; 
    private int size; 


    public ISudoku(int size){ 
     this.size = size; 
     sudokuboard = new int[size][size]; 
     sudokuboolean = new boolean[size][size]; 
    } 

    public void setNumber(int i, int j, int number, boolean given){ 
     sudokuboard[i][j] = number; 
     sudokuboolean[i][j] = given; 
    } 
    public int NumberOnBoard(int i, int j){ 
     return sudokuboard[i][j]; 
    } 
    public int getSize(){ 
     return size; 
    } 

    public String toString(){ 
     String string = ""; 
     for(int i = 0; i < size; i++){ 
      for(int j = 0; j < size; j++){ 
       if(sudokuboolean[i][j]){ 
        string += "<" + sudokuboard[i][j] + "> "; 
       } 
       else{ 
        string += sudokuboard[i][j] + " "; 
       } 
       if(j == 2 || j == 5){ 
        string += " "; 
       } 
      } 
      string += "\n"; 
      if(i == 2 || i == 5){ 
       string += "\n"; 
      } 
     } 

     return string; 
    } 
} 
public abstract class ISudokuSolver { 

    public abstract boolean solveSudoku(ISudoku sudoku);  

    public boolean containedin3x3(ISudoku sudoku,int row, int col, int value){ 
     int firstRow = row/3 * 3; 
     int firstCol = col/3 * 3; 

     for(int i = firstRow; i < firstRow+3; i++){ 
      for(int j = firstCol; j < firstCol+3; j++){ 
       if(!(i == row && j == col)){ 
        if(sudoku.NumberOnBoard(i,j) == value){ 
         return true; 
        }     
       } 
      } 
     } 
     return false; 
    } 
    public boolean containedinRoC(ISudoku sudoku,int row, int col, int value){ 
     for(int i = 0; i < 9;i++){ 
      if(i != col){ 
       if(sudoku.NumberOnBoard(row,i) == value){ 
        return true; 
       } 
      } 
      if(i != row){ 
       if(sudoku.NumberOnBoard(i,col) == value){ 
        return true; 
       } 
      } 
     } 
     return false; 
    } 
} 
public class BacktrackingISudokuSolver extends ISudokuSolver{ 

    public boolean solveSudoku(ISudoku sudoku){ 
     backtracking(0,1,sudoku); 
     return true; 
    } 

    private boolean backtracking(int row,int number, ISudoku sudoku){ 
     for(int i = 0; i < sudoku.getSize();i++){ 
      if(!containedinRoC(sudoku,row,i,number) && !containedin3x3(sudoku,row,i,number)){ 
       sudoku.setNumber(row,i,number,false); 
       if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number != 9){ 
        number += 1; 
       } 
       if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number == 9){ 
        return true;       
       } 
       else{ 
        if(backtracking(row+1,number,sudoku)){ 
         return true; 
        } 
        else{ 
         sudoku.setNumber(row,i,0,false); 
        } 
       } 
      } 
     } 
     return false; 
    } 

} 
public class Examples extends BacktrackingISudokuSolver { 

    public static void main(String[] args) { 


     ISudokuSolver solver = new BacktrackingISudokuSolver(); 
     ISudoku sudoku = new ISudoku(9); 
     System.out.println(sudoku); 
     System.out.println("Beispiel 1: "); 
     System.out.println("Lösbar? (Erwartet): Ja"); 
     System.out.println("Benötigte Zeit? (Erwartet): 15 ms (Intel i5 3,8 Ghz)"); 
     long start = System.currentTimeMillis(); 
     boolean solvable = solver.solveSudoku(sudoku); 

     long end = System.currentTimeMillis(); 
     System.out.println("Lösbar?: " + solvable); 
     System.out.println("Benötigte Zeit: " + (end - start) + " ms"); 
     System.out.println(sudoku); 
    } 
} 
+1

我建議你在調試器中調試你的代碼,並捕獲這個異常,這樣你就可以看到它發生的原因。 –

+0

和堆棧跟蹤?它應該明確指出哪一行負責超出範圍的數組訪問。 –

+0

http://stackoverflow.com/questions/5554734/what-c​​auses-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it – assylias

回答

2

沒有在異常的行號,我要去責怪i在第二循環中containedin3x3條件。身體永遠不會改變i,因此j會增加,直到超出範圍。

for(int i = firstRow; i < firstRow+3; i++){ 
    for(int j = firstCol; i < firstCol+3; j++){ 
+0

y改變了一個問題ty,這樣一個愚蠢的錯誤^^ – Akyro

0

你鏈接的圖像中的堆棧跟蹤似乎暗示這一行:

return sudokuboard[i][j]; 

該錯誤消息指示越界-索引的值是9。

假設您正在求解9x9數獨,變量sudokuboard將具有9,9的維數。在Java中,數組索引從0開始,因此該數組的兩個索引的有效範圍爲0到8.

在我這方面需要更多的分析才能找出爲什麼這種方法被稱爲不正確的參數,因爲它是這樣的;該作業最好通過調試器來處理。

更新

似乎是這個問題,但我不知道如何去改變它

一般來說,「知道如何去改變它」依賴於確定只在哪裏以及如何事情變成梨形。正如我已經建議的那樣,這是一個調試器有用的功能之一。你真的應該學會如何使用它。

堆棧跟蹤的其餘部分也可以用於此目的。在這種情況下,它蘊涵在第10行BacktrackingISudokuSolver.backtracking()這個方法調用:

containedinRoC(sudoku,row,i,number) 

它並不需要的代碼的大量研究得出結論,這可能是出界的唯一參數是row,其值是本身是對第19行遞歸調用backtracking()的一個參數(再次指向堆棧跟蹤)。隨後,考慮該行和它周圍的那些:

09  for(int i = 0; i < sudoku.getSize();i++){ 
10   if(!containedinRoC(sudoku,row,i,number) && !containedin3x3(sudoku,row,i,number)){ 
11    sudoku.setNumber(row,i,number,false); 
12    if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number != 9){ 
13     number += 1; 
14    } 
15    if(row == sudoku.getSize()-1 && i == sudoku.getSize()-1 && number == 9){ 
16     return true;       
17    } 
18    else{ 
19     if(backtracking(row+1,number,sudoku)){ 
20      return true; 
21     } 
22     else{ 
23      sudoku.setNumber(row,i,0,false); 
24     } 
25    } 
26   } 
27  } 

看着代碼,並在特定的19行,你看到了什麼辦法,這個方法可能被稱爲帶有有效參數,但執行用無效參數遞歸調用?這就是你需要解決的問題。

+0

似乎是問題,但我不知道如何改變它^^ – Akyro

+0

然後,返回sudokuboard [i] [j]之前使用aswell和不回答一個問題,所以我不知道 – Akyro

+0

@Akyro,我已經更新我的答案還有額外的指導,但你需要自己承擔一些負擔。 –

相關問題