我正在开发一个程序,该程序使用适当的数值填充一个空的9x9数组。我的验证方法可行,因为我已经通过简单的迭代回溯方法对其进行了测试。 我目前的方法是随机选择一行和一列并放置一个合适的值,我也通过使用递归来实现回溯。这是我的求解器函数:
void solve (int board[9][9]) {
static int counter = 0;
int val = 0;
int row = 0;
int col = 0;
if (counter == 81) {
print (board, counter);
exit(1);
}
while (1) {
row = rand() % 9;
col = rand() % 9;
if (board[row][col] == 0)
break;
}
++counter;
for (int i = 1; i < 10; i++) {
val = i;
if (ok (board, row, col, val)) {
board[row][col] = val;
solve (board);
}
}
--counter;
}
现在我遇到的问题是我从未达到81,我的函数在此之前终止,我假设堆栈变空并返回main。你能帮我理解我犯的错误吗?谢谢。
答案 0 :(得分:2)
当您尝试使用适当的值填充Sudoku网格时,最终会陷入死锁:您尝试查找值的单元格无法在不破坏Sudoku规则的情况下填充。举一个简单的例子,考虑第一行为[x, 2, 3, 4, 5, 6, 7, 8, 9]
且第一列为[x, 1, 8, 2, 3, 4, 5, 6, 7]
的网格。 x无法填写,但所有其他值都遵循规则。
在您的情况下,当发生死锁时,ok
条件不会被1到9中的任何值满足,并且执行返回到一层递归,前一个单元格,其中一个值已被选中。在那里,该函数尝试下一个可能的值。
如果某个单元格中存在死锁(即多级死锁),则执行会再次返回一层递归,但该值仍然存在。这导致后续ok
条件在成功时失败,因为这些“鬼”值。对于简单的死锁不会发生此问题,因为该值保持为0。
在for
循环之后,您需要将board[row][col]
的值设置回0。