软件工程实践2019第三次作业
GitHub项目地址
https://github.com/983911953/031702239
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60min | 60min |
Estimate | 估计这个任务需要多少时间 | 24h | 25h |
Development | 开发 | 5h | 3h |
Analysis | 需求分析 (包括学习新技术) | 2h | 6h |
Design Spec | 生成设计文档 | 2h | 2h |
Design Review | 设计复审 | 30min | 30min |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30min | 30min |
Design | 具体设计 | 1h | 1h |
Coding | 具体编码 | 2h | 1.5h |
Code Review | 代码复审 | 1h | 1h |
Test | 测试(自我测试,修改代码,提交修改) | 2h | 5h |
Reporting | 报告 | 2h | 2h |
Test Repor | 测试报告 | 1h | 1h |
Size Measurement | 计算工作量 | 30min | 30min |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 1h | 1h |
合计 | 25h |
解题思路
- 因为有玩过数独,所以刚开始拿到题目后,觉得应该用排除法,我刚开始认为的排除法是每一个格子都设置一个一维数组,用来记录该格子有阶数大小数量的可能性,然后排除该格子所在的行、列、宫格有的数值的可能性。然后我又百度了一下怎么解数独题目,看到了两个名词排除法和唯余法,发现我把唯余法也认为是排除法了,之后庆幸我百度了。
- 在思考题目的时候,我想先把Visual Studio community 2017弄好(以前安装过一次,但那时候不会用,于是就卸载了,用原本的devcpp),但没想到困扰了我两天(大部分时间在等我的电脑什么时候重装好和安装软件)。安装VS 2017后,发现还是不会用,而且不知道为什么devcpp编译表示“不存在iostream这个文件或目录”。经过努力学习后,我艰难的用起了VS 2017。然后在弄完命令行处理技术(① https://blog.csdn.net/dcrmg/article/details/51987413 ②C++ Primer Plus(第六版)中文版 P772 )后,我有陷入了新的难题文件的读取、写入和追加(① https://www.cnblogs.com/Yogurshine/p/3677201.html ②如上的书),花了一个下午,终于能用来做题目了。
- 写代码前,先分工了一下:
-
命令行参数举例
Sudoku.exe -m 9 -n 2 -i input.txt -o output.txt
-
主函数用来读写文件
int main(int argc, char *argv[]) { shudu sudu; int m = atoi(argv[2]); int n = atoi(argv[4]); int mm = m * m; ifstream inf; ofstream outf; inf.open(argv[6]); if (!inf) { cout << "intput error " << endl; exit(1); } outf.open(argv[8]); if (!outf) { cout << "output error " << endl; exit(1); } for (int i = 0; i < n; ++i) { char ch;![](https://img2018.cnblogs.com/blog/1796955/201909/1796955-20190925223401032-615031718.png) sudu.shudu_re(m); for (int j = 1; j <= m; ++j) { for (int k = 1; k <= m; ++k) { inf >> ch; sudu.sd[j][k] = ch - '0'; } } sudu.total(m); for (int j = 1; j <= m; ++j) { for (int k = 1; k <= m; ++k) { ch = sudu.sd[j][k] + '0'; outf << ch; outf << " "; outf << " "; } outf << endl; } outf << endl; } inf.close(); outf.close(); return 0; }
-
一个数独类用来处理本身的数据
class shudu { public: int order; int order_order; int sd[10][10]; int sd_count[10][10]; bool flag[10][10]; bool check[10][10][10]; void shudu_re(int m); void check_2(int j, int k, int m); void check_3(int j, int k, int m); void total(int m); };
-
计算模块接口的设计与实现过程
计算模块接口部分的性能改进
去掉了一些优先级低的处理(原本是为了代码中类数据整体上统一)
代码质量分析
CPU使用率
我的代码只为求唯一解的数独,若要想求多解,应该在我的代码求出唯一的多解模板的基础上用dfs就可以了。我单纯的认为这应该比只有dfs的快。
计算模块部分单元测试展示
三宫格
四宫格
五宫格
六宫格
七宫格
八宫格
第八宫格前两题是多解,感谢一位同学的帮助,不然我就又要思考好久,才会去用DFS去验算
九宫格
计算模块部分异常处理说明
-
计算模块的主要是对有宫格数独的宫格处理有点小失误
for (int xxx = ((i - 1) / col) * col, x_x = 1; x_x <= col; ++x_x) { for (int yyy = ((j - 1) / row) * row, y_y = 1; y_y <= row; ++y_y) { if (sd[xxx + x_x][yyy + y_y] == 0 && check[xxx + x_x][yyy + y_y][sd[i][j]] == false) { check[xxx + x_x][yyy + y_y][sd[i][j]] = true; sd_count[xxx + x_x][yyy + y_y]--; } } }
该两重循环的循环条件一开始写反了,导致六宫格和八宫格的计算错误,而且八宫格的样例不是唯一解(一开始不知道不是为一街),导致更正后结果仍有问题,以为我的算法有问题,不过幸好有同学的帮助,得以更快的解决(算法没问题)。
具体代码见 github