Java 如何修复:数独解算器堆栈溢出问题
我正在尝试用Java创建一个数独解算器,一般来说,我对编程和Java都是新手。我真的不知道如何处理这种错误。 我一直收到堆栈溢出错误 我尝试了不同的代码,没有一个有效,但无论如何,这是我的最新代码:Java 如何修复:数独解算器堆栈溢出问题,java,recursion,stack-overflow,backtracking,sudoku,Java,Recursion,Stack Overflow,Backtracking,Sudoku,我正在尝试用Java创建一个数独解算器,一般来说,我对编程和Java都是新手。我真的不知道如何处理这种错误。 我一直收到堆栈溢出错误 我尝试了不同的代码,没有一个有效,但无论如何,这是我的最新代码: public class Sudoku { private int[][] values; private boolean [][] writable; private static final int ZERO = 0; private static final
public class Sudoku {
private int[][] values;
private boolean [][] writable;
private static final int ZERO = 0;
private static final int SIZE = 9;
//just a normal constructor that sets which values are changeable and which aren't. only values equal to zero are changeable.
public Sudoku(int[][] values) {
this.values = new int[SIZE][SIZE];
for(int row = 0; row< SIZE ; row++)
{
for(int col = 0; col< SIZE; col++)
{
this.values[row][col] = values[row][col];
}
}
writable = new boolean[values.length][values[1].length];
for(int i = 0;i < writable.length;i++)
{
for(int j = 0; j<writable[1].length;j++)
{
if(values[i][j] == ZERO)
{
writable[i][j] = true;
}
}
}
}
public void setValues(int row,int col ,int value) //changes the value if the value was changeable.
{
if(writable[row][col])
{
values[row][col]= value;
}
}
public int getValue(int row,int col) {
return values[row][col];
}
public boolean isWritable(int row,int col)
{
return writable[row][col];
}
private boolean ConflictAtRow(int row , int num)
{
for(int i = 0;i < SIZE;i++)
if(getValue(row,i) == num)
return true;
return false;
}
private boolean ConflictAtCol(int col, int num)
{
for(int i = 0;i<SIZE;i++)
if(getValue(i,col) == num)
return true;
return false;
}
private boolean ConflictAtBox(int row, int col, int num)
{
int r = row - row %3;
int c = col - col %3;
for(int i = r;i<r+3;i++)
{
for(int j = c;j<c+3;j++)
{
if(getValue(i, j) == num && row != i && col != j)
return true;
}
}
return false;
}
private boolean ConflictAt(int row, int col, int num)
{
return ConflictAtBox(row, col, num) && ConflictAtCol(col,num) && ConflictAtRow(row, num); //line 108
}
public boolean solve(int row,int col)
{
int nextRow = (col < 8) ? row:row+1;
int nextCol = (col +1)%9;
for (row = nextRow; row < SIZE; row++) {
for (col = NextCol; col < SIZE; col++) {
if(isWritable(row,col))
{
for (int num = 1; num <= 9; num++) {
if(!ConflictAt(row,col,num)) //line 118
{
setValues(row,col,num);
if(solve(nextRow,nextCol)) //line 122
return true;
}
setValues(row,col,ZERO);
}
}return !ConflictAt(row,col,getValue(row,col)) &&
solve(nextRow,nextCol);;
}
}return true;
}
依此类推……一旦控件第一次进入
solve()
方法,并且如果直到第122行所有if
条件都计算为true
,则再次调用solve()
方法
问题是,每次控件点击这个方法时,就好像它是第一次执行它一样。因为条件没有变化(循环的总是从0
开始)
这意味着,solve()
问题是,每次控件点击这个方法时,就好像它是第一次执行它一样。因为条件没有变化(
循环的总是从0
开始)
这意味着,solve()
方法会被反复调用,直到堆栈内存耗尽。简单看一下,我有点困惑。由于数独板有9*9=81
单元格,递归深度应受到81
的限制;你试过使用调试器吗?我不知道如何调试我还没有学会调试,但我会检查一下。从表面上看,实现看起来不错;我想知道问题是什么。而且,如果谜题无法解决,该方法似乎返回false。并成功终止。也许你的意思是成功终止。从一个简单的看,我有点困惑。由于数独板有9*9=81
单元格,递归深度应受到81
的限制;你试过使用调试器吗?我不知道如何调试我还没有学会调试,但我会检查一下。从表面上看,实现看起来不错;我想知道问题是什么。而且,如果谜题无法解决,该方法似乎返回false。并成功终止。也许你的意思是成功终止。好的,谢谢,我试着编辑solve方法,这样它就不会重复调用相同的循环了。但我还是遇到了同样的问题。我将更改后的代码添加到帖子中。您发布的代码不应编译<代码>行
和列
已经声明为方法参数,您正在尝试将它们重新声明为循环迭代器。此外,每次调用solve(…)
时,for循环仍然从索引0
开始。很抱歉,我仍然在编辑代码,当我发布注释“我的坏”时,无论如何,嗯。。它现在确实编译并工作了,以一种奇怪的方式,它花了一分钟来显示任何结果,但却显示了错误的结果。哈哈,谢谢,我试着编辑solve方法,这样它就不会重复调用相同的循环了。但我还是遇到了同样的问题。我将更改后的代码添加到帖子中。您发布的代码不应编译<代码>行和列已经声明为方法参数,您正在尝试将它们重新声明为循环迭代器。此外,每次调用solve(…)
时,for循环仍然从索引0
开始。很抱歉,我仍然在编辑代码,当我发布注释“我的坏”时,无论如何,嗯。。它现在确实编译并工作了,以一种奇怪的方式,它花了一分钟来显示任何结果,但却显示了错误的结果。哈哈
Exception in thread "main" java.lang.StackOverflowError
at Sudoku.Sudoku.ConflictAt(Sudoku.java:108)
at Sudoku.Sudoku.solve(Sudoku.java:118)
at Sudoku.Sudoku.solve(Sudoku.java:122)
at Sudoku.Sudoku.solve(Sudoku.java:122)
at Sudoku.Sudoku.solve(Sudoku.java:122)
at Sudoku.Sudoku.solve(Sudoku.java:122)