【发布时间】:2017-05-21 20:21:54
【问题描述】:
我的程序有问题,它应该解决数独并在完成后打印,但问题是,程序看起来永远不会结束,打印已解决的数独后会出错。
这是程序正在执行的循环:
它也不应该打印字段,如果我在开始时删除System.out.print(f+"\n");,它只会打印错误。
代码:
public class Sudoku {
public static void main(String[] args) throws SolvedException {
Field field = new Field();
field.fromFile("test1.txt");
SudokuSolver solver = new SudokuSolver();
solve(field, 0, 0, solver);
System.out.println(field);
}
public static void solve(Field f, int i, int j, SudokuSolver solver) {
System.out.print(f+"\n");
if ( j >= Field.SIZE) {
//we are done (return true now!)
solver.done=true;
return;
}
if (f.isEmpty(i, j)) {
for (int val = 1; val <=9; val++) {
if (f.tryValue(val, i, j)){
if (j>=Field.SIZE-1){
solve (f, i+1, 0, solver);
if ( solver.done ) {
// This halts the loop here:
return;
}
f.clear(i, j);
} else {
solve(f,i,j+1, solver);
if ( solver.done ) {
// This halts the loop here:
return;
}
f.clear(i, j);
}
}
}
} else if (j>=Field.SIZE-1) {
solve(f,i+1,0, solver);
} else {
solve(f,i,j+1, solver);
}
}
}
数独解法
public class SudokuSolver{
/* Set true when the solve is done */
public boolean done;
}
错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Field.isEmpty(Field.java:101)
at Sudoku.solve(Sudoku.java:30)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:67)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:67)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:67)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:38)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:71)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.solve(Sudoku.java:50)
at Sudoku.main(Sudoku.java:9)
任何想法如何停止循环并打印正确的字段? System.out.println(field) 在解决方法中不是这个?
【问题讨论】:
-
鉴于
throws SolvedException,它可能应该在// we are done部分中设置为throw new SolvedException();。值得注意的是,它是一个bad idea to use exceptions to control the flow 之类的。另一个注意事项是大量的非尾递归也可能导致随机堆栈溢出异常。 -
简而言之,递归就是函数调用自身的地方。每次发生这种情况时,您都会得到另一个“堆栈帧”——基本上所有函数使用的局部变量都被存储了。如果一个函数多次调用自己,堆栈就会变得太大并且“溢出”。尾递归是一种优化,本质上堆栈帧可以被“重用”,因为编译器注意到局部变量不再使用,允许无限递归发生。另请参阅 this answer 以获得更深入的比较。
-
@Mercy 在发布好答案并解决您的问题后,不要删除“请删除此问题”的问题正文。如果你以这种方式编辑它会混淆其他人。
-
@Mercy 那么你不应该首先发布这个问题。请先熟悉本网站的运作方式。
-
我不明白你的问题是什么。 taskinoor 告诉您,不允许您删除问题的重要部分,并且您继续这样做。我已将此问题标记为版主锁定此问题并防止您进一步操纵。
标签: java loops recursion backtracking sudoku