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 > d
d-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;
}
}
}
}

心路历程

通过阅读构造之法,让我明白了一个工程,一个程序的设计,并不是最后跑出来结果就算完事了,开发人员的能力也是可以量化的,要一改之前大一大二那种打题目的思维方式,多从工程的角度去看待问题,去分析和设计程序。