1、删除readFromFile函数的函数体,考察学生的文件读写能力;
2、删除Solve函数;
3、删除solveSudoku函数的函数体。其中:
a)参数const char a[][COL]表示初盘二维数组;
参数char b[][COL]表示解的二维数组
需要将其添加进去
/*
* 数独学生端程序
* 左妍
* 计算机科学与技术系
* 2017/6/12
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define CORRECT 0
#define WRONG -1
#define MAXNUM 1000 /*数独游戏个数*/
int checkSudoku(const char a[][COL]){
int i,j,x,y;
for( i = 0; i < ROW ; i++){
for(j = 0 ; j < COL ; j++){
for(x = 0 ; x < COL ; x++)
if(a[i][x] == a[i][j] && x != j )
return WRONG;
for(x = 0 ; x < ROW ; x++)
if(a[x][j] == a[i][j] && x != i )
return WRONG;
for(x = i/3*3 ; x < i/3*3+3 ; x ++)
for(y = j/3*3 ; y < j/3*3+3 ; y++)
if(a[x][y] == a[i][j] && (x != i && y != j))
return WRONG;
}
}
return CORRECT;
}
void printSudoku(const char a[][COL]){
int i,j;
printf("\n ┌────┬────┬────┐\n");
for( i = 0 ; i < ROW ; i++){
if(i != 0 && i%3 == 0) printf(" ├────┼────┼────┤\n");
printf(" │");
for( j = 0 ; j < COL ; j++){
if(j != 0 && j%3 == 0) printf(" │");
if(a[i][j])
printf(" %d",a[i][j]);
else printf(" ");
}
printf(" │\n");
}
printf(" └────┴────┴────┘\n");
}
void readFromFile(char a[][COL], const char filename[]){
// To Be Solved
// 从文件filename中读取到的数独初盘存储到数组a[][COL]中
}
void solveSudoku(const char a[][COL], char b[][COL]){
// To Be Solved
// 参数const char a[][COL]表示初盘二维数组;
// 参数char b[][COL]表示解的二维数组。
}
int main(){
char starting_grid[ROW][COL]={0};
char result[ROW][COL]={0};
char filename[50];
int rr;
double time_from, time_to, time_sum = 0;
int i;
for( i = 0; i < MAXNUM ; i++){
sprintf(filename,"sudoku\\%04d.txt",i);
readFromFile(starting_grid,filename);
printf("\n\n *%4d *",i);
printSudoku(starting_grid);
time_from = clock();
solveSudoku(starting_grid,result);
time_to = clock();
time_sum += time_to - time_from;
printSudoku(result);
rr = checkSudoku(result);
if( rr == WRONG){
printf("Something goes wrong...\n");
return WRONG;
}
else printf(" Correct!!!\n");
printf(" ==============================");
}
printf("\n Congretulations! ToTal Time:%fs\n",time_sum / CLOCKS_PER_SEC);
return 0;
}
基于深度搜索实现版本
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define ROW 9
#define COL 9
#define CORRECT 0
#define WRONG -1
#define MAXNUM 1000 /*数独游戏个数*/
#define bool int
#define true 1
#define false 0
bool DFS(char b[][COL], int n);
int checkSudoku(const char a[][COL]){
int i,j,x,y;
for( i = 0; i < ROW ; i++){
for(j = 0 ; j < COL ; j++){
for(x = 0 ; x < COL ; x++) // 列
if(a[i][x] == a[i][j] && x != j )
return WRONG;
for(x = 0 ; x < ROW ; x++) // 行
if(a[x][j] == a[i][j] && x != i )
return WRONG;
for(x = i/3*3 ; x < i/3*3+3 ; x ++) // 9宫格内
for(y = j/3*3 ; y < j/3*3+3 ; y++)
if(a[x][y] == a[i][j] && (x != i && y != j))
return WRONG;
}
}
return CORRECT;
}
void printSudoku(const char a[][COL]){
int i,j;
printf("\n ┌───────┬───────┬───────┐\n");
for( i = 0 ; i < ROW ; i++){
if(i != 0 && i%3 == 0) printf(" ├───────┼───────┼───────┤\n");
printf(" │");
for( j = 0 ; j < COL ; j++){
if(j != 0 && j%3 == 0) printf(" │");
if(a[i][j]!=' ')
printf(" %d",(a[i][j]-'0')); /*怀疑这里出问题,原来是 printf(" %d",a[i][j]);*/
else
printf(" %c",a[i][j]);
}
printf(" │\n");
}
printf(" └───────┴───────┴───────┘\n");
}
void readFromFile(char a[][COL], const char filename[]){
// To Be Solved
// 从文件filename中读取到的数独初盘存储到数组a[][COL]中
FILE *fp = NULL;
if((fp = fopen(filename, "r"))==NULL){
printf("Fail to open file!\n");
return;
}
int i=0, j=0;
while(!feof(fp)){
fscanf(fp,"%s",a[i]);
for(j=0;i<ROW&&j<COL;j++)
if(a[i][j]=='0')
a[i][j]=' ';
i++;
}
fclose(fp);
}
void writeToFile(char a[][COL], const char filename[]){
// To Be Solved
// 数独初盘存储到数组a[][COL]中存储到文件filename
FILE *fp;
if((fp = fopen(filename, "w+") )==NULL){ /*打开文件写模式*/
printf("cannot open the file.\n"); /*判断文件是否正常打开*/
return;
}
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++)
if(a[i][j] == ' ')
fputc('0',fp);
else
fputc(a[i][j],fp);
fputc('\n',fp);
}
fclose(fp);
}
void solveSudoku(const char a[][COL], char b[][COL]){
// To Be Solved
// 参数const char a[][COL]表示初盘二维数组;
// 参数char b[][COL]表示解的二维数组。
for(int i=0;i<ROW;i++)
for(int j=0;j<COL;j++)
b[i][j] = a[i][j];
DFS(b,0);
}
int main(){
char starting_grid[ROW][COL]={0};
char result[ROW][COL]={0};
char filename[50];
int rr;
double time_from, time_to, time_sum = 0;
int i;
for( i = 0; i < MAXNUM ; i++){
sprintf(filename,"E:\\C\\Test\\sudoku\\%04d.txt",i);
readFromFile(starting_grid,filename);
printf("\n\n *%4d *",i);
printSudoku(starting_grid);
time_from = clock();
solveSudoku(starting_grid,result);
time_to = clock();
time_sum += time_to - time_from;
printSudoku(result);
rr = checkSudoku(result);
if(rr == WRONG){
printf("Something goes wrong...\n");
//return WRONG;
continue;
}
else
printf(" Correct!!!\n");
printf(" ==============================");
}
printf("\n Congretulations! ToTal Time:%fs\n",time_sum / CLOCKS_PER_SEC);
system("pause");
}
bool Check(char b[][COL],int n, char key){
int x,y,i,j;
x = n / 9;
y = n % 9;
// 检查纵坐标方向
for(i=0;i<ROW;i++)
if(b[i][y] == key && x!=i)
return false;
// 检查横坐标方向
for(j=0;j<COL;j++)
if(b[x][j] == key && y!=j)
return false;
// 检查小宫格
for(i = x/3*3 ; i < x/3*3+3 ; i ++) // 9宫格内
for(j = y/3*3 ; j < y/3*3+3 ; j++)
if(b[i][j]==key && (x != i && y != j))
return false;
return true;
}
bool DFS(char b[][COL], int n){
int x,y;
x = n / 9;
y = n % 9;
if(n>80)
return true;// 退出条件
if(b[x][y]!=' '){ //不为空
return DFS(b,n+1);
}else{
char c;
//遍历各个情况:枚举
for(int i=1;i<=9;i++){
c = i+'0';
if(Check(b, n, c)){
b[x][y] = c;
// 继续搜索
bool res = DFS(b,n+1);
if(res==true)
return res;
/* 如果构造不成功,还原当前位 */
b[x][y] = ' ';
}
}
}
return false;
}
我做了一些改动,辅助输出好看点