github地址
https://github.com/kevintrey/081700537.git
PSP表格
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|
计划 | 20 | 30 |
估计这个任务需要多少时间 | 360 | 480 |
开发 | 240 | 360 |
需求分析 (包括学习新技术) | 240 | 240 |
生成设计文档 | 10 | 10 |
设计复审 | 30 | 40 |
代码规范 (为目前的开发制定合适的规范) | 5 | 5 |
具体设计 | 20 | 30 |
具体编码 | 240 | 360 |
代码复审 | 60 | 60 |
测试(自我测试,修改代码,提交修改) | 60 | 120 |
报告 | 20 | 20 |
测试报告 | 30 | 30 |
计算工作量 | 20 | 10 |
事后总结, 并提出过程改进计划 | 20 | 15 |
解题思路描述
刚拿到题目,第一次接触到数独,首先通过百度百科了解数独的规则,再通过一些数独游戏自己玩了几个简单的数独,再在博客上看一些关于设计程序解数独的思路,最终选定用深度搜索的方法来构建数独。题目还设计到文件输入输出和命令行参数,通过阅读一些博客找回文件输入输出的知识,以及新学习了命令行传参。
算法关键,所运用的函数,单元测试的设计
算法关键在于用深度搜索构造数独,函数分别用到了input()输入函数,output()输出函数,DFS()深搜,Check()判别是否合法的函数。首先通过input函数将宫格大小,盘面等信息输入,接下来由DFS()构造数独,用递归的方法,通过深度搜索测试每个点的每个可能,只要行不通就回溯到最初的点上,DFS()内会用到Check()来判别该点是否合法,最后再用output函数输出到文本output.txt。测试input函数和output函数的时候,在input.txt文件中写入一个数独盘,先不管是否构造完数独,直接用output函数,在检测output.txt文件中是否输出了数独盘。测试check函数时,编写了一小段代码若返回true则输出1,反之则输出0,用多个例子测试来完善函数,最后测试DFS时,与前面几个已经确定正确函数配合测试。
程序性能的改进
暂时没有想到改进程序的方法
关键代码展示
/* 判断key填入n时是否满足条件 /
bool Check(int n, int key,int c)
{
/ 判断n所在横列是否合法 /
for (int i = 0; i < c; i++)
{
/ j为n竖坐标 */
int j = n / c;
if (num[j][i] == key) return false;
}
/* 判断n所在竖列是否合法 */
for (int i = 0; i < c; i++)
{
/* j为n横坐标 */
int j = n % c;
if (num[i][j] == key) return false;
}
if(c>3)
{
/* x为n所在的小九宫格左顶点竖坐标 */
int x = n / 9 / 3 * 3;
/* y为n所在的小九宫格左顶点横坐标 */
int y = n % 9 / 3 * 3;
/* 判断n所在的小九宫格是否合法 */
for (int i = x; i < x + 3; i++)
{
for (int j = y; j < y + 3; j++)
{
if (num[i][j] == key) return false;
}
}
}
/* 全部合法,返回正确 */
return true;
}
/* 深搜构造数独 /
int DFS(int n,int d)
{
/ 所有的都符合,退出递归 /
if (n > dd-1)
{
sign = true;
return 0;
}
/* 当前位不为空时跳过 /
if (num[n/d][n%d] != 0)
{
DFS(n+1,d);
}
else
{
/ 否则对当前位进行枚举测试 /
for (int i = 1; i <= d; i++)
{
/ 满足条件时填入数字 /
if (Check(n, i,d) == true)
{
num[n/d][n%d] = i;
/ 继续搜索 /
DFS(n+1,d);
/ 返回时如果构造成功,则直接退出 /
if (sign == true) return 0;
/ 如果构造不成功,还原当前位 */
num[n/d][n%d] = 0;
}
}
}
}