软件工程实践2017第二次作业
链接
解题思路
1、拿到题目后,觉得这题目和八皇后的题挺像的,都是行列冲突问题,因此觉得可以通过将一个99的数独图变成9个33的图,对每张33的图进行数字的填充,例如先将1填入9张小图中。按以上思路写完程序后,在行数下移的同时还需要在对应的图中找到下一个数填入的地址,产生了可能会跳过某一行填入数值的问题,便又加了个在33图中找数填入的位置,效率变得很慢。
2、第二版是发现了还有dfs算法的解法,然后修改了一下思路,还是先将数逐一填入,然后每一行优先填入。考虑到第一版在小图中寻找数值需要很大的时间消耗,就用一个二维数组来记录数字填入了哪一张小图。
设计实现过程
代码结构其实很简单,num_pic函数找出行列对应的图号,judge函数判断该位置能否放入对应值,dfs函数进行数值的回溯。
代码说明
核心代码是进行for循环中每一行进行填入数值的判断与递归。
void Sudo::dfs(int row, int z, int end) {
if (row == 9)
{
if (z == end){
output();//输出
co++;
if (co == num)
{
outfile.close();
exit(0);
}
return;
}
else {
int newZ = z + 1;//防止+1时z数值超过10
if (newZ >= 10)
{
newZ -= 9;
}
dfs(0, newZ, end);//递归下一个数
}
}
for (int i = 0; i < 9; i++) {
int num = num_pic(row, i);//图号
if (judge(row, i, z) && ju[z][num] == 0)//判断行列及图
{
da[row][i] = z;
ju[z][num] = 1;
dfs(row + 1, z, end);//递归下一行
//回溯后将值复原
da[row][i] = 0;
ju[z][num] = 0;
}
}
}
测试运行
输入n=10000
代码性能
cout比printf的性能低好多,最后改成输出到文件时运行时间又缩短很多。以下是n==10000时的性能数据
psp表格(写完题才发现有这个表格,所以数据可能不太准确,然后vs2017一直加载不上测试工具,测试和代码覆盖率都没弄)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
·Estimate | ·估计这个任务需要多少时间 | 450 | 440 |
Development | 开发 | ||
·Analysis | ·需求分析(包括学习新技术) | 60 | 60 |
·Design Spec | ·生成设计文档 | 20 | 10 |
·Design Review | ·设计复审 (和同事审核设计文档) | ||
·Coding Standard | ·代码规范 (为目前的开发制定合适的规范) | ||
·Design | ·具体设计 | 90 | 90 |
·Coding | ·具体编码 | 120 | 120 |
·Code Review | ·代码复审 | 40 | 30 |
·Test | ·测试(自我测试,修改代码,提交修改) | 50 | 50 |
Reporting | 报告 | ||
·Test Report | ·测试报告 | 30 | 0 |
·Size Measurement | ·计算工作量 | 15 | 20 |
·Postmortem & Process Improvement Plan | ·事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 455 | 410 |