我在以下程序中有一个 IndexOutOfBounds 异常。它由三个文件组成:
重要的是其中只有两个,GUI 工作正常。这是第一个:
interface SudokuObserver {
public void modified(int i, int j);
}
public class SudokuData
{
public int[][] feld = new int[9][9];
public SudokuObserver obs = null;
public SudokuData()
{
int i,j;
for (i=0; i<9; i++) {
for (j=0; j<9; j++) {
feld[i][j] = 0;
}
}
}
public int getNumber(int x, int y)
{
return feld[x][y];
}
public void setNumber(int x, int y, int v)
{
feld[x][y] = v;
if (obs != null)
obs.modified(x, y);
}
public void setObserver(SudokuObserver o)
{
obs = o;
}
所以数独字段被分配为一个 9x9 整数数组。下面的文件称为 SudokuSolver,它有一个算法可以将每个正方形的可能数字写入 ArrayList。然后第二个算法的工作原理如下:他找到具有最小可能数字的正方形,将保存在 ArrayList 中的第一个数字设置在该正方形上并递归执行,因此他再次开始定义每个正方形的可能数字,选择可能性最少的那个,然后选择第一个将其放入该字段。执行此操作时,for 循环会遍历每个正方形的可能数字。
import java.util.*;
public class SudokuSolver
{
SudokuData data;
public SudokuSolver(SudokuData d)
{
data = d;
}
{
/*Pseudoalgorithm:
- Inserts the numbers 1-9 into a Collection called res
- Looks at line x, which numbers are in there and erases them out of the
collection
- Looks at column y, which numbers are in there and erases them out of the
collection
- Looks in the 3x3 Square (x,y) which numbers are already in there and erases
them out of the collection
- Gives back the possible candidates for that field
*/
在这里我初始化我的 ArrayList。
public ArrayList<Integer> offen(int x, int y)
{
ArrayList<Integer> res = new ArrayList<Integer>();
/* The collection is saved in an ArrayList */
int k = 0;
在这里,我只是在我的 ArrayList 中填写数字 1-9。
for (int i=1;i<10;i++)
{
res.add(i);
}
现在是困难的部分:我从零循环到九,然后循环 k。该行与给定的 x 保持一致,j 在列上运行,所以我得到了给定行中的每个正方形,并且在每个正方形中,我检查了 1-9 中的每个数字。注意:索引从 0-9 开始,而元素从 1-9 开始,因此 k 必须为 0-9,因为 get() 方法将索引作为输入。如果有任何合规性,我会从 ArrayList 中删除该元素。
for (int j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[x][j] == (res.get(k)))
res.remove(k);
}
列、常量列和 j 循环的内容与上述相同。
for (k=0;k<9;k++)
{
if (this.data.feld[j][y] == res.get(k))
res.remove(k);
}
}
现在我在两个新变量中输入了我的输入,只是因为我之前在下面输入了错误的变量名称的代码部分。
int m = x;
int n = y;
这是 3x3 方块的部分,我在 if 条件下执行此操作,所以这只是 9 个部分之一,我不想将它们全部发布在这里,因为它们只是在一些常数上有所不同。我检查我的输入 x,y 在哪个正方形中,然后循环遍历正方形并检查那里有哪些数字,这些数字仍然在我的 ArrayList 中并删除它们。
if (m<=2 && n<=2)
{
for (m=0;m<3;m++)
{
for (n=0;n<3;n++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[m][n] == res.get(k))
res.remove(k);
}
}
}
}
现在我返回 ArrayList
return res;
}
//findSolution() finds a Solution
public boolean findSolution()
{
/*Possible Strategy:
- Find the square, which has the fewest possible candidates
- If there are more than one candidates, who have the minimum of candidates,
take any of them
- If there are no more open candidates, there is a solution found. Return
true
- Loop over the candidates of this square and by setting the first possible
candidate into this square[x][y]
- Call the method findSolution() recursive to find in dependence of the set
value the values for the other fields
If there is a blind alley, take the next possible candidate (Backtracking!)
*/
int j = 0;
int k = 0;
int x = 0; // x coordinate of the field with the fewest open candidates
int y = 0; // y coordinate of the field with the fewest open candidates
int counter_offene_felder = 0; // counts the number of open fields
int min = 9;
我正在循环 j 和 k,查看可能的候选数是否超过 0,这意味着我正在遍历整个数独字段并计算开放字段的数量。
for (j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if ( this.offen(j,k).size() >= 0)
{
counter_offene_felder += 1;
}
如果数字小于 min = 9 个可能的候选者,我将其作为最小值并保存该字段的坐标
if ( (this.offen(j,k)).size() < min )
{
x = j;
y = k;
}
}
}
现在我用尽可能少的候选者为字段初始化和 ArrayList,并使用我的 offen 方法将它们放入这个 ArrayList
ArrayList<Integer> candidate_list = this.offen(x,y);
for (k=0;k<this.offen(x,y).size();k++)
{ // runs over candidates
int v = this.offen(x,y).get(k); // takes the first candidate
this.data.setNumber(x,y,v); // writes the first candidate into square [x][y]
this.findSolution(); // calls findSolution() recursive
}
If there are no more open fields, I've found a solution
if (counter_offene_felder == 0)
{
return true;
}
else return false;
}
}
问题是,我在第 39 行,索引 8 大小 8 处得到一个 IndexOutOfBounds 异常。但我不知道为什么。:(