我本人正在上C课程。当我运行代码时,什么也没发生(什么也不打印),而且我找不到问题所在。
而且我发现我的检查功能很笨拙,如何改进它,使其变得纤薄而简单?
这是我的代码。
#include <stdio.h>
#define ON 1
#define OFF 0
#define SIZE 8
void initial(int (*table)[SIZE]);
void setqueen(int (*table)[SIZE], const int row);
int check(const int (*table)[SIZE], const int row, const int col);
void prtable(const int (*table)[SIZE]);
int main(void)
{
int table[SIZE][SIZE];
int row = 0;
initial(table);
setqueen(table, row);
return 0;
}
void initial(int (*table)[SIZE])
{
int row, col;
for (row = 0; row < SIZE; row++)
for (col = 0; col < SIZE; col++)
table[row][col] = OFF;
}
/*
place a queen(set value = 1) in the first column of the first row and
check there is no conflict. if there is a conflict, count and move to
next column. if there is conflict in every column(count = 8), return.
if there is no conflict, call it recursively. when it place all queens,
print the table.
*/
void setqueen(int (*table)[SIZE], const int row)
{
int c = 0;
int count = 0;
for ( ; c < SIZE; c++) {
table[row][c] = ON;
if (check(table, row, c) == ON) {
table[row][c] = OFF;
count++;
continue;
}
if (count == SIZE)
return;
if (row != SIZE - 1)
setqueen(table, row + 1);
else
prtable(table);
}
}
void prtable(const int (*table)[SIZE])
{
int row, col;
for (row = 0; row < SIZE; row++) {
for (col = 0; col < SIZE; col++)
printf("%2d", table[row][col]);
putchar('\n');
}
putchar('\n');
}
int check(const int (*table)[SIZE], const int row, const int col)
{
int r = 0;
int c = 0;
for (r = 0; r < SIZE; r++)
if (r != row && table[r][col] == ON)
return ON;
for (c = 0; c < SIZE; c++)
if (c != col && table[row][c] == ON)
return ON;
for (r = row + 1, c = col + 1;
(r >= 0 && r < SIZE) || (c >= 0 && c < SIZE);
r++, c++)
if (table[r][c] == ON)
return ON;
for (r = row + 1, c = col - 1;
(r >= 0 && r < SIZE) || (c >= 0 && c < SIZE);
r++, c--)
if (table[r][c] == ON)
return ON;
for (r = row - 1, c = col + 1;
(r >= 0 && r < SIZE) || (c >= 0 && c < SIZE);
r--, c++)
if (table[r][c] == ON)
return ON;
for (r = row - 1, c = col - 1;
(r >= 0 && r < SIZE) || (c >= 0 && c < SIZE);
r--, c--)
if (table[r][c] == ON)
return ON;
return OFF;
}
最佳答案
您不会像预期的那样递归。setqueen
调用setqueen
尝试所有可能性,但如果失败,则尝试将皇后放在for(c)
循环的同一行上,这将失败。
在prtable
的开头调用setqueen
来查看算法在做什么,您将看到:
1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
然后,算法将尝试在第5行放置一个皇后,但失败,但不尝试移动先前放置的皇后。
setqueen
还应删除后跟的table[row][c] = OFF;
,并在对setqueen
的递归调用失败时移至下一个(因此它应返回一个值)。除此之外,在我看来
count
和c
是同一件事,您可以在for循环中而不是之前(更易读)初始化c,在检查中添加有关每个for循环检查内容的注释(列,行,...),并避免对检查返回值使用ON和OFF(不清楚含义)。关于c - 八个皇后在C中递归不打印任何内容,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24485922/