软件工程实践2017第二次作业
软件工程实践第二次作业
1. github项目地址:https://github.com/laizhiping/SEP
2. 估计耗费的时间
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟 | 实际耗时(分钟 |
---|---|---|---|
Planning | 计划 | 20 | |
.Estimate · | 估计这个任务需要多少时间 | 20 | |
Development | 开发 | 1080 | |
.Analysis | 需求分析 (包括学习新技术) | 600 | |
.Design Spec | 生成设计文档 | 20 | |
.Design Review | 设计复审 (和同事审核设计文档) | 30 | |
.Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | |
.Design | 具体设计 | 20 | |
.Coding | 具体编码 | 100 | |
.Code Review | 代码复审 | 80 | |
.Test | 测试(自我测试,修改代码,提交修改) | 80 | |
Reporting | 报告 | 80 | |
.Test Report | 测试报告 | 30 | |
.Size Measurement | 计算工作量 | 20 | |
.Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | |
合计 | 1180 |
3.解题思路
刚开始拿到题目时说实话是比较无措的,因为一看到这题读完题目就觉得是深搜的题,对于深搜我是比较苦恼的,还有递归也是比较烦。而且感觉和大一C语言实践的那题马跳棋盘比较类似,就比较惧怕。后面去百度,找到的各种生成数独的方法也是采用深搜递归的比较多,无奈最后还是决定硬着头皮上。基本的想法就是先自己构造出一个已解答且符合要求的数独,然后因为数独的特点是不重复,所以我交换源数独中的两个数字可以构成一个新的数独,为了达到交换的目的,我首先对第0行1—8位置((0,0)的已经固定,不参与)的数进行全排列,对于生成的进行同时第1-2行交换(0行由于题目要求不能动),3—5行交换,6—8行交换。这个过程就要用到深搜。但是后面发现这样比较耗时,与是采用动态生成地 方法,即对第一除第0个数字进行全排列,然后根据第一行生成数独剩余行而非交换源数独,这样就可避免深搜。如果要求个数达不到,再考虑交换行。
4.设计实现
文件组织:Sudoku工程文件下含3个C++文件,main.cpp和sudoku.cpp以及sudoku.h。其中main.cpp是主方法,Sudoku.h为实现功能的成员变量及函数,sudoku.cpp为实现功能的函数,sudoku.cpp中的generator为产生数独的主要函数。
5.代码说明
实现数独的生成关键函数:
void Sudoku::generator(int n)
{
int arr[] = { 6, 1, 2, 3, 4, 5, 7, 8, 9 };
for (int i = 0; i < N; i++)
matrix[0][i] = arr[i];
count = 0;
while (next_permutation(matrix[0] + 1, matrix[0] + N))//对第一行的第1到N-1个数进行全排列
{
init_generator();//由数独第一行产生整个数独
print(matrix);
++count;
if (count == n)
break;
if (n<40320) //若所求个数小于全排列个数减一则不进行交换行操作
continue;
exchange_row(n);
}
}
init_generator()
函数为根据第一行生成整个数独矩阵,生成方法是将第一列的前三个放在最后,然后后面六个往前移;第3-5行为1-3行的数据依次往前移一个单位,第一个放在最后;6-8行为3-5行的数据依次往前移一个单位。至此生成整个矩阵。print(matrix)
将生成的矩阵输出到文件。exchange_row(n)
为通过交换行产生矩阵并输出到文件。由于8个数的全排列可以产生40320种矩阵,故当n小于这个数时直接全排列而不进入exchange_row(n)
交换行以提高效率。
6.测试运行
测试运行的结果如上,输入为1000000。
7.性能上所花费的时间
如上图为输入为1000000时所生成的性能分析图,由性能分析知,影响时间的主要瓶颈在于exchange_row()
函数,而其中又是由于每个循环都调用了三次的的输出行函数print_Mrows
,故此为影响性能的最大因素,故需减少print_Mrows,改进方法即为减少该函数的调用或者修改此函数提高性能,这里我改进的方法是减少调用,就是前述4中代码说明的if (n<40320)
,其它改进策略由于时间有限就没有去尝试。
8.实际花费的时间
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟 | 实际耗时(分钟 |
---|---|---|---|
Planning | 计划 | 20 | 30 |
.Estimate · | 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 1080 | 1440 |
.Analysis | 需求分析 (包括学习新技术) | 600 | 800 |
.Design Spec | 生成设计文档 | 20 | 40 |
.Design Review | 设计复审 (和同事审核设计文档) | 30 | 20 |
.Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 20 |
.Design | 具体设计 | 20 | 30 |
.Coding | 具体编码 | 100 | 350 |
.Code Review | 代码复审 | 80 | 60 |
.Test | 测试(自我测试,修改代码,提交修改) | 80 | 120 |
Reporting | 报告 | 80 | 90 |
.Test Report | 测试报告 | 30 | 60 |
.Size Measurement | 计算工作量 | 20 | 20 |
.Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1180 | 1640 |
9.总结
这次的软件工程实践,已经充分得看出了自己存在的不足,之前没有写总结,是想等最终的结果出来,把暴露出的问题全部总结起来。此次作业带来的收获有:
1. 充分看出了自己的代码能力,实在是弱的可以,思路有了,把他变成代码总是会遇到这种那种的问题,原本以为很简单的部分实现起来确实各种的不行,究其原因也是自己敲的少吧。
2.自己的实在是不够细心,本来是很小问题,总是会忘记这忘记那,检查的时候也不够细心,就比如说提交的两次修改,第一次是由于github push失败,导致仓库里的文件并非最终版。本来这个是很好解决的,只要把他下载下来运行测试下肯定是可以发现的。但是没有去做。其次是第二次修改的地方,愣是把0,1,2写成了1,2,3,这个也是自己检查的时候没有仔细去看,只看了个数,却没有去看数独的正确与否,这个也是很基本的问题。
3.自己的心态不是很好,一旦长时间敲代码,心情就会变得烦躁,自己的代码也就写的一塌糊涂,作为一个程序员,这也是最致命的。
接下来的时间里,我会认认真真的审视自己,从不足处入手,一步步改变,争取在较短的一段时间里能够变成自己想要的模样。