首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >thread main java.lang.arrayindexoutofboundsexception 9中的java异常

thread main java.lang.arrayindexoutofboundsexception 9中的java异常
EN

Stack Overflow用户
提问于 2015-04-21 02:36:49
回答 2查看 554关注 0票数 1

我现在正在尝试写一个带回溯的数独解算器,我已经解决了一些问题,但我不知道现在该做什么。

这就是问题:

代码语言:javascript
复制
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)

当我运行代码时

我不期望得到正确的代码给我,我只是感谢每个人的帮助。

代码语言:javascript
复制
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);
    }
}
EN

回答 2

Stack Overflow用户

发布于 2015-04-21 02:44:03

如果在异常中没有行号,我将归咎于containedin3x3中第二个循环条件中的i。主体从不更改i,因此j会一直递增,直到它超出边界。

代码语言:javascript
复制
for(int i = firstRow; i < firstRow+3; i++){
  for(int j = firstCol; i < firstCol+3; j++){
票数 2
EN

Stack Overflow用户

发布于 2015-04-21 02:45:55

您链接的图像中的堆栈跟踪似乎包含以下行:

代码语言:javascript
复制
    return sudokuboard[i][j];

错误消息指示越界索引值为9。

假设您正在求解一个9x9 sudoku,变量sudokuboard的维数为9,9。在Java语言中,数组索引从0开始,因此该数组的两个索引的有效范围都是0到8。

我需要更多的分析才能弄清楚为什么调用该方法时使用了不正确的参数;这项工作最好通过调试器来处理。

更新

似乎是问题所在,但我不知道如何改变它

一般来说,“知道如何改变它”取决于确定事情在哪里以及如何发展成梨形。正如我已经建议的,这是调试器有用的事情之一。你真的应该学习如何使用它。

堆栈跟踪的其余部分也可以用于此目的。在本例中,它在BacktrackingISudokuSolver.backtracking()的第10行隐含了此方法调用

代码语言:javascript
复制
containedinRoC(sudoku,row,i,number)

不需要对代码进行太多研究就能得出结论:唯一可能越界的参数是row,它的值本身就是第19行对backtracking()的递归调用的参数(再次引用堆栈跟踪)。然后,考虑一下这条线和它周围的线:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29755779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档