我在C中制作一个数独生成器,但是当我启动程序时,它会在无限循环中随机出现。有时会打印所有行,有时只打印一行等等。(见下图) 这是代码 有什么问题?
#include <string.h>
#include <stdlib.h>
#include "sudoku.h"
#include <stdio.h>
#include <time.h>
int dimension = 9;
int main(int argc, char** argv){
int dimension = 9;
int j ,k,i ;
int ** sudo = malloc(sizeof(*sudo)*dimension);
for ( j = 0; j< dimension; j++){
sudo[j] = malloc(sizeof(int)*dimension);
}
riempiSudoku(sudo);
return 0;
void riempiSudoku(int** sudo){ //fill sudoku
int j,i,k,f;
int len;
//srand ( time(NULL));
int ran;
for (i=0;i<dimension;i++){
for(j=0;j<dimension;j++){
if(!thereisNumber(sudo, i,j)){
printf("\nNon ci sono numeri\n");//no solution, stop the program
exit(0);
}
printf("%d ", sudo[i][j]);
}
printf("\n");
}
}
int checkRow(int** sudo, int row, int value){ //check if the number is in the row
int i;
for (i = 0; i<dimension; i++){
if (sudo[row][i] == value)
return 1;
}
return 0;
}
int checkCol(int** sudo, int col, int value){//check if the number is in the col
int i;
for (i = 0; i<dimension; i++){
if (sudo[i][col] == value)
return 1;
}
return 0;
}
int checkSquare(int** sudo, int row, int col, int value){
int i, j;
for(i= (row/3)*3; i<(row/3)*3 +3; i++){
for(j=(col/3)*3; j<(col/3)*3 +3; j++){
if(sudo[i][j] == value)
return 1;
}
}
return 0;
}
int thereisNumber(int** sudo, int i,int j){
int options[dimension];
int len;
for (len=0; len<dimension; len++)
options[len] = len + 1; // populate the array with 1..9
while (len) {
int ran = rand() % len; // select an index into the list
int digit = options[ran]; // get the number from the available list
if (checkSquare(sudo,i,j,digit) || checkRow(sudo,i,digit) || checkCol(sudo,j,digit))
options[ran] = options[--len]; // remove digit from list
else{
sudo[i][j]= digit;
return len>0;
}
}
return 0; //thereisNumber(sudo,i,j-1);
}
这些是截图 http://imgur.com/lQpFOPf 这是gdb的结果 http://imgur.com/qp8omko
答案 0 :(得分:1)
如果没有可能的解决方案,你的程序就会陷入僵局 - 正如@BLUEPIXY评论的那样。
但是你的程序无法检测到它,它不断尝试更多随机数。我建议使用卡片中使用的Fisher-Yates shuffle之类的东西,从可能的数组中删除不成功的候选者。
int options[dimension];
int len;
for (len=0; len<dimension; len++)
options[len] = len + 1; // populate the array with 1..9
while (len) {
int ran = rand() % len; // select an index into the list
int digit = options[ran]; // get the number from the available list
if (checkSquare(sudo,i,j,digit) || checkRow(sudo,i,digit) || checkCol(sudo,j,digit))
options[ran] = options[--len]; // remove digit from list
else break;
}
return len > 0; // 0 if failed to find digit
如果功能失败,您需要能够“撤消”数字展示位置的历史记录。那是你的下一个任务!
编辑而不是“撤消”功能,在每个数字位置都可以实现我展示的“可能性阵列”。解决方案比您想象的要复杂得多,可能需要递归解决方案。