软件工程实践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

posted @ 2019-09-25 22:42  Wasted  阅读(168)  评论(1编辑  收藏  举报