软件工程实践2017第二次作业

Github项目地址:https://github.com/emperor-fa/My-repository
作业地址:https://edu.cnblogs.com/campus/fzu/SoftwareEngineering2015/homework/859


● 项目相关要求

2)在开始实现程序之前,在下述PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间。

  • PSP表格在下方。

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

  • 不重复,数独终盘数量

    数独中的数字排列千变万化,那么究竟有多少种终盘的数字组合呢?
    6,670,903,752,021,072,936,960(约为6.67×10的21次方)种组合,2005年由Bertram Felgenhauer和Frazer Jarvis计算出该数字,并将计算方法发布在他们网站上,如果将等价终盘(如旋转、翻转、行行对换,数字对换等变形)不计算,则有5,472,730,538个组合。数独终盘的组合数量都如此惊人,那么数独题目数量就更加不计其数了,因为每个数独终盘又可以制作出无数道合格的数独题目。

    由此可见,就算固定一个数,题目要求的N依旧远小于总数,因此在1000000以内重复的可能性很小,若是每生成一个数独,都与之前生成的数独比较,不仅增加了麻烦,还浪费了时间,所以不重复应该不予考虑。

  • 接下来就要生成随机数独
    在这里,我采取从左往右从上到下,每一个方格都从1-9中随机选取,选中的删除,进行判断(比较该方格的行、列、宫是否有相同的数),若不符合则重新选取;若选取符合的数则进行下一个方格;若是当达到有一个方格没有符合的数时,则返回上一个方格重新选取;直到最后一个方格置数完毕。
    判断:由于是按照从左到右从上到下的顺序,所以只需要比较本行该格之前本列该格之上的数即可。至于九宫则是先取到本九宫的第一个索引值再按照一样的顺序比较。


4)设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?

  • 代码设计一个Sudoku类,类私有成员有一个9*9二维矩阵,公有函数有构造函数Sudoku,输出函数display,判断函数judge,填充函数setnum。其中,Sudoku函数用于初始化,使各个方格为0且第一个为要求的数;判断函数为填充函数作出判定填充的数是否符合数独规则。输出函数在填充完毕后用于输出到控制台界面和指定Sudoku.txt中。由于我的算法过于简单,我就没画流程图。

5)代码说明。展示出项目关键代码,并解释思路与注释说明。(5‘)

bool Sudoku::setnum(int row, int col)   //填数
{
	vector<int> num;      //创建一个从1-9的数组用于填充
	for (int i = 0; i <mysize; i++)
		num.emplace_back(i + 1);
	while (!num.empty())
	{
		int randindex = rand() % num.size();     //生成一个随机序号
		int randnum = num[randindex];         //取得数组内随机序号的值
		num.erase(num.begin() + randindex);     //删除掉所取值
		mysudoku[row][col] = randnum;         //赋值
		if (judge(row, col) == false)         //判断是否符合
			continue;                           //不符合则重新选数
		if (row == mysize - 1 && col == mysize - 1)    //是否整个九宫格赋值完成
			return true;
		int nextrow, nextcol;
		if (col == mysize - 1)      //下一格
		{
			nextrow = row + 1;
			nextcol = 0;
		}
		else
		{
			nextrow = row;
			nextcol = col + 1;
		}
		bool nextset = setnum(nextrow, nextcol);      //深度搜索
		if (nextset)
			return true;
	}
	if (num.empty())           //无解
	{
		mysudoku[row][col] = -1;
		return false;
	}
}

6)测试运行。程序必须是可运行的,展示出程序运行的截图。PS:如果有扩展需求或者更高级的需求,请秀出来,有额外加分。


7)记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图,并展示你程序中消耗最大的函数。PS:如果采用Visual Studio Community 2015开发,使用C++或者C#语言实现,VS 2015的性能分析工具可自动生成。

这是我的程序在电脑上的程序性能分析图。(10000个,release)

打出10000个就已经花了这么多时间,很显然,我的程序需要优化。图中可以看出是display函数占据时间最多,所以也就是我的io输出较慢。


8)在你实现完程序之后,在下述PSP表格记录下你在程序的各个模块上实际花费的时间。

  • PSP表格在下方。

● 遇到的困难及解决方法

  • 困难描述
    程序敲完后,我试着能生成数独也就不管了,可是到了学校,写博文的性能分析时发现我的算法还不够简便,打出10000个就花了这么多时间,远远达不到同学敲的程序运行速度,所以急需优化。
  • 做过哪些尝试
    想要优化程序,只能改变算法,比如把每格1-9改为或者按数字1-9先后填,本想把同学的代码借鉴一下,后来想想算了,还是我自己解决。可是由于思路不明,每运行程序总是卡住,没输出。最终我没写出来,只能把目前的程序上交。
  • 是否解决
    很遗憾,最终并未解决。
  • 有何收获
    虽然经过长时间尝试还是失败了,但是我锻炼了思维方式,了解新的逻辑方法,增强了解决问题的能力,加强了分析和实践能力。

● PSP
(以下并不包括尝试改变和优化算法的时间)

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
· Estimate · 估计这个任务需要多少时间 7*60 8.5*60
Development 开发
· Analysis · 需求分析 (包括学习新技术) 1*60 40
· Design Spec · 生成设计文档 20 20
· Design Review · 设计复审 (和同事审核设计文档) 5 10
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 10
· Design · 具体设计 10 10
· Coding · 具体编码 2*60 3*60
· Code Review · 代码复审 30 30
· Test · 测试(自我测试,修改代码,提交修改) 1*60 1.5*60
Reporting 报告
· Test Report · 测试报告 1*60 80
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
合计
posted @ 2017-09-10 18:33  霸气发哥  阅读(137)  评论(0编辑  收藏  举报