2020软件工程作业03

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/software-engineering-2017-1
这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/software-engineering-2017-1/homework/10494
 这个作业的目标  实现一个命令行程序Sudoku
 作业正文  如下
 其他参考文献

 https://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html

https://www.cnblogs.com/xinz/p/5044037.html

http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html

https://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html

1.Github项目地址:https://github.com/yyp0820/20177577sudoku/blob/master/SRC

2.PSP表格:

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning  计划 60 60
Estimate 估计这个任务需要多少时间 800 1200
Development 开发 140 140
Analysis 需求分析 (包括学习新技术) 60 80
Design Spec 生成设计文档 30 30
Design Review 设计复审 30 30
Coding Standard 代码规范 (为目前的开发制定合适的规范) 40 45
Design 具体设计 60 80
Coding 具体编码 480 600
Code Review 代码复审 120 150
Test 测试(自我测试,修改代码,提交修改) 90 120
Reporting 报告 30 30
Test Repor 测试报告 30 30
Size Measurement 计算工作量 30 60
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 45 60
合计   2045 2715

3.思路分析:一看到这个题目压根看不懂题目意思,题目要求:
1.程序能生成不重复的数独终局至文件;
2.程序能读取文件内的数独问题,求一个可行解并将结果输出到文件;

要想解决这个问题就得先问度娘数独游戏的规则:数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。———引用自《数独_百度百科

在了解了题目要求和规则以后,我马上想到的一种算法就是回溯法:对于生成数独终局,我们只要按顺序一个个填数字就好了,每填完一个数字都检查它所在的行,列和宫是否满足数独的规则,若满足则填下一个数字,若不满足则回溯。并且由于题目要求中的第二点只要求一个可行解,因此1、2两个要求感觉实质上是一样的。当然还有一种更简单的算法叫矩阵生成法,可是由于能力有限,学习完回溯脑袋就大了,还是老老实实用回溯吧。

3.设计实现过程:采用了回溯法,思路如下:
设了一个9X9的二维数组a[9][9],然后判断 值k是否可以插入某个点 a[i][j]
①该数组所有横向没有存在过k值
for(n=0;n<9;n++)
if(a[i][n]==k)return 0;
②该数组纵向没有存在过k值
for(m=0;m<9;m++)
if(a[m][j]==k)return 0;
③该点位于的九宫格3X3区间没有存在过k值
xm=(i/3)*3,xn=(j/3)*3;
for(m=xm;m<xm+3;m++)
for(n=xn;n<xn+3;n++)
if(a[m][n]==k)return 0;
然后开始搜索的过程:9X9总共81个格子,就用一个数字n作为标记i,j坐标点的变量(i=n/9; j=n%9;),即:80就相当于最后一个格子 8/9=8,8%9=8
如果n等于80,那么就表示已经遍历到最后一个点了,如果满足条件的话就找到最终解了。
如果n不等于80,表示还要继续往下试,即用不同的k值试探当前i,j点是否可以放下,回归后回溯就ok了。

void SD(int a[9][9],int n)//求解
{
int i,j;
int b[9][9];
for(i=0;i<9;i++)
for(j=0;j<9;j++)
b[i][j]=a[i][j]; //用b进行尝试
i=n/9; j=n%9; //行列
if(a[i][j]!=0) //如果该位置固定
(n==80)?print(b):SD(b,n+1);
else
{
int k; //试数
for(k=1;k<=9;k++)
if(test(b,i,j,k)) //可以
{
b[i][j]=k;
n==80?print(b):SD(b,n+1);
b[i][j]=0; //回溯 
}
}
}

4.实现结果:

 

5.性能分析,代码改进:

 

第一次调试报错C4996,这是VS的版本问题,scanf返回值被忽略,在项目属性添加:_CRT_SECURE_NO_WARNINGS,这样调试结果就没问题了。

对代码进行性能分析,探测CPU的利用率,可以看出外部代码占用最多,达到百分之九十七,其次是_src_common_main和_src_common_main_sesh函数,这两个函数没有可以优化的地方所有没有进行更改。

6.单元测试:

7.实验总结:这次个人项目做的非常坎坷,一大把原因就是对VS和C++都不熟悉,在性能测试和单元测试阶段我的VS出了很多问题,让我整个人心态都不太好了。不过也学习到了回溯法,我之前从来没有想过对一个代码进行优化,也不知道仅仅IO上的改变能对一个程序的性能造成如此大的影响,越发让我感觉自己还需要不断提高,差的实在是远。

自我评分:

作业头 Github项目地址 代码要求经过code quality analysis工具的分析并消除所有警告 PSP表格估计 PSP表格实际 解题思路描述 代码如何组织 关键函数画出流程图 单元测试的设计 找出性能瓶颈 改进 展示关键代码 解释思路与注释说明 结合构建之法心路历程和思想 总分
2 1 2 0.5 0.5 1 0.5 0 0 0.5 0 0.5 0.5 0.5 9.5
原文地址:https://www.cnblogs.com/0820yyp/p/12574825.html