软件工程实践第二次作业

it2022-05-05  122

作业链接

1.github链接

2.PSP

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)Planning· 计划4070· Estimate· 估计这个任务需要多少时间3040Development· 开发500680· Analysis· 需求分析 (包括学习新技术)100150· Design Spec· 生成设计文档00· Design Review· 设计复审 (和同事审核设计文档)00· Coding Standard· 代码规范 (为目前的开发制定合适的规范)2010· Design· 具体设计6080· Coding· 具体编码300350· Code Review· 代码复审3050· Test· 测试(自我测试,修改代码,提交修改)100150Reporting· 报告150180· Test Report· 测试报告100110· Size Measurement· 计算工作量3020· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划3030合计14901920

3.解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的心路历程。


(刚开始拿到题目之后)

看到这个题目的时候,内心是非常拒绝的,一开始看到了数独,有点茫然,对于数独的了解并不大深,通过了解,原来就是九宫格里的每行每列要有1-9的数字,并且不重复,每个宫里也是如此,没能想到合适的方法,就开始了漫漫找资料的历程。一开始搜索的关键字就是“随机生成数独”,利用深度优先遍历的方式,然后通过判断每个点是否正确摆放生成数独,对于这个方法的理解有些困难,然后继续找看看有没有其他的方法。首先随机数法对于本次的题目来说肯定是不大合适的,数字庞大效率低下,后面又找到了回溯法和置换法两种方法,觉得回溯法这个方法比较好理解,于是就选择了使用这个方法。

回溯法

先设置一个全为0的九宫格,然后从第一个为0的格子开始填入随机数,并判断是否满足数独的要求(即每行每列没宫不可有重复数字),继续向下查找为0格子填入,如果没有可选数,进行回溯,换掉前面的数字,继续执行,以此类推,知道81个格子全不为零的时候,就生成了一个数独。下面是具体代码

4.设计实现过程

分为四个函数:

5.代码说明。

rightplace函数:

bool sudokutest::rightplace(int g, int h)//检测九宫格里的每个数字是否符合数独要求 { int row, col; row = g / 9; col = g % 9; int i, j; for (i = 0; i < 9; i++) //对该数字所在的行查找是否有相同的数字 { if (sudoku[row][i] == h) return false; } for (i = 0; i < 9; i++) //对该数字所在的行查找是否有相同的数字 { if (sudoku[i][col] == h) return false; } int a, b; a = row / 3; b = col / 3; for (i = a * 3; i < a * 3 + 3; i++) //在每一个宫里判断是否有相同的数字出现 { for (j = b * 3; j < b * 3 + 3; j++) { if (sudoku[i][j] == h) return false; } } return true; }

put函数:

void sudokutest::put(int n) { int row, col; row = n / 9; col = n % 9; int i; if (n == 81)//达到81,说明九宫格已经被填满 { pd = true; return; } if (sudoku[row][col] != 0)//找到没有被填的格子 { put(n + 1); } else { if (n % 9 == 0)//每一行将数组随机调换 random_shuffle(&(a[0]), &(a[9])); for (i = 0; i < 9; i++) { if (rightplace(n, a[i])) { sudoku[row][col] = a[i]; put(n + 1); if (pd) return; sudoku[row][col] = 0; } } } }

main函数主要:

int main(int argc, char *argv[])//实现可以从cmd输入sudoku.exe -c 1000格式 { int i, j, temp = 0; int k = 0, num = 0; int p = 0; stringstream stream; string na,ne; int n; if (argc!=3) { cout << "ERROR!!!more or less sentences" << endl; return 0; } else { ne = argv[1]; if (ne == "-c") { na = argv[2]; int l = na.length(); for (int m = 0; m < l; m++)//判断输入的字符串是不是纯数字 { if (na[m] <= 57 && na[m] >= 48)//数字0-9的ascii码为48-57,若发现数字,p就加一 { p++; } } if (p != l)//如果最后的p与字符串长度不相同,就说明输入的字符串不是纯数字 { cout << "please enter an integer" << endl; return 0; } stream << na;//将字符串转换成数字 stream >> n; stream.clear(); freopen("./sudoku.txt", "w", stdout); while (n--) { sudokutest s; s.first(); pd = false; s.put(0); s.print(); } } else { cout << "Your input format is wrong!!!" << endl; } } } 最主要的就是这三个代码,put函数使用回溯方法进行数字的放入,right place用来判断每行每列每宫是否有重复,是否符合数独的规定。因为测试要使用cmd,一开始不知道要使用argc ,argv[]这种方法,不能实现sudoku.exe -c 1000这样语句的实现。由于会出现-c abc或者-c 12r这样的错误语句,故需要判定输入的字符串是否为纯数字。

6.测试运行。

cmd输入测试: 输出结果:

7.效能分析

直接用该代码进行性能测试,应该是不行的,就很奇怪

后面觉得应该是main函数的问题,就把它改成了直接输入的形式,去掉了argc,argv[]方法进行测试,测试的数量为1000

从中可以看到print函数占用的最大,一开始我是使用cout进行输出的,之前听说过进行大量输出的时候,printf好像效率会高一点,于是我就把输出改成printd

emmmm,就快了三秒,然后就继续看看还有什么更高效的输出方式,搜到了putchar方法

从时间量上来看,putchar的时间还比printf多了一点点,一脸茫然。不知道还有什么其他的可以优化的方法了。

发现同样的一段代码,在同学的电脑上测试,和在自己的电脑上测试,时间差了几乎一半,我使用的是vs2015,同学的是vs2017,不知道有没有和版本有关。


关于单元测试,看了一些教程试了好多次,但一直都会有报错,所以只能暂时搁置了,以后会继续琢磨琢磨。


在性能分析上,相较于其他同学的,时间耗费还是很长的,效率还是不高,希望在今后的学习过程中能将自己的代码能力进一步加强。本次作业通过查找资料,也学习到了很多新的知识,懂得了怎么查看代码的性能,总体来说,还是很有收获的。


转载于:https://www.cnblogs.com/linqiaona/p/7511477.html

相关资源:各显卡算力对照表!

最新回复(0)