次のプログラムで IndexOutOfBounds 例外が発生しました。次の 3 つのファイルで構成されます。
重要なのはそのうちの 2 つだけです。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 に書き込むアルゴリズムを持っています。次に、2 番目のアルゴリズムは次のように機能します。最小の可能な数を持つ正方形を見つけ、ArrayList に保存されている最初の数をその正方形に設定し、これを再帰的に実行するため、各正方形の可能な数の定義からやり直します。 、可能性の数が最も少ないものを取得し、最初のものを選択してそのフィールドに入れます。それを行っている間、for ループは、各正方形の可能な Numbers に対して実行されます。
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);
}
ここからが難しい部分です。j を 0 から 9 までループし、次に 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);
}
}
以前に間違った変数名で以下のコード部分を入力したという理由だけで、2 つの新しい変数で入力を取得します。
int m = x;
int n = y;
ここに 3x3 の正方形の部分があります。if 条件でこれを行うので、これは 9 つの部分の 1 つにすぎません。ここにすべてを投稿したくはありません。いくつかの定数が異なるだけだからです。入力 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;
}
数が < 最小 = 9 候補未満の場合、それを最小としてそのフィールドの座標を保存します
if ( (this.offen(j,k)).size() < min )
{
x = j;
y = k;
}
}
}
今、私は可能な限り少ない候補を持つフィールドのArrayListを初期化し、それらを私のoffen-methodでこの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 行目の Index 8 Size 8 で IndexOutOfBounds Exception が発生することです。しかし、その理由はわかりません。:(