【发布时间】:2014-02-07 12:22:33
【问题描述】:
这是我被要求为一堂课做的一个程序,它必须解决一个 nxn 大小的数独难题 使用回溯算法,但不需要检查子方块,只检查行和列。 我的程序的问题是回溯部分永远不会触发:(每当它到达无法继续的点时,它就会停止并打印板,而不是擦除最后一次尝试并尝试其他东西。 提前抱歉缺少 cmets,我目前只能访问代码(不在家里),但它主要是非常简单的函数,问题出在 aux_solveSudoku 和 sudoku 函数中,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define UNASSIGNED 0
bool aux_SolveSudoku(int n, int array[][n]);
bool SolveSudoku(int n, int array[][n], int row, int col);
bool check(int n, int array[][n], int row, int col, int number);
bool CheckRow(int n, int array[][n], int row, int number);
bool CheckCol(int n, int array[][n], int col, int number);
bool CheckIfFull(int n, int array[][n]);
void printArray(int n, int array[][n]);
int main()
{
int n;
scanf(" %d", &n);
int array[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
scanf(" %d",&array[i][j]);
}
}
if (aux_SolveSudoku(n, array) == true)
printArray(n, array);
else
printf("No Solution!");
return 0;
}
bool aux_SolveSudoku(int n, int array[][n]){
for (int row = 0; row < n; row++){
for (int col = 0; col < n; col++){
if (SolveSudoku(n, array, row, col) && CheckIfFull(n, array))
return true;}
}
return false;
}
bool SolveSudoku(int n, int array[][n], int row, int col){
if(array[row][col] != UNASSIGNED)
return true;
for(int i=1; i<=n; i++){
if(check(n, array, row, col, i)){
array[row][col] = i;
if(SolveSudoku(n, array, row, col))
return true;
array[row][col] = UNASSIGNED;
}
}
return false;
}
bool check(int n, int array[][n], int row, int col, int number){
return (!CheckRow(n, array, row, number) && !CheckCol(n, array, col, number));
}
bool CheckRow(int n, int array[][n], int row, int number){
for (int col = 0; col < n; col++){
if (array[row][col] == number){
return true;}
}
return false;
}
bool CheckCol(int n, int array[][n], int col, int number){
for (int row = 0; row < n; row++){
if (array[row][col] == number){
return true;}
}
return false;
}
bool CheckIfFull(int n, int array[][n]){
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
if(array[i][j] == UNASSIGNED)
return false;
}
}
return true;
}
void printArray(int n, int array[][n]){
for (int row = 0; row < n; row++){
for (int col = 0; col < n; col++){
printf("%d ", array[row][col]);}
printf("\n");
}
}
这是程序的一组示例数据:
5
0 0 0 2 4
3 1 0 0 2
0 2 1 0 5
2 0 3 0 0
0 0 0 0 0
这显然有一个解决方案:
1 3 5 2 4
3 1 4 5 2
4 2 1 3 5
2 5 3 4 1
5 4 2 1 3
不幸的是,程序没有找到解决方案,但我不明白为什么没有。
【问题讨论】:
-
只是让您知道那不是有效的 c 代码。它是使用 c 函数的 C++。 c 中没有 bool 类型。您必须改用 int。
-
@chasep255:C99和C11中有
_Bool类型;如果使用标头<stdbool.h>,还有bool类型,代码使用<stdbool.h>(C++ 代码不会这样做)。不要忘记,MSVC 编译器实现的标准已经有将近 25 年的历史(今年晚些时候,它将有 25 年的历史),而不是该标准的最新版本。 -
实际上,这不是 C++ 代码还有另一个原因;它使用 C99 VLA(可变长度数组),它不是任何标准 C++ 版本的一部分(尽管 G++ 编译器确实接受它们作为扩展)。
-
首先要做的事情之一是确保输入的数据与您认为输入的数据相符;在致电
aux_SudokuSolver()之前打印数独板。调用入口点SudokuSolver()和递归函数aux_SudokuSolver()(反转当前角色)可能更传统。然而,这是琐事。你在 1x1 和 2x2 板上测试过吗? 3x3呢?代码为我编译干净(好)。我想在SudokuSolver()的每个(递归)条目上打印正在处理的板,这样我就可以看到它在做什么。
标签: c recursion backtracking solver