软工实践2019第三次作业

1. 【Github项目地址

2. 【PSP表】

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

3.【 解题思路描述】:借鉴一下人为解数独的过程,把它用代码实现。

最贴近的便是:
  • 先遍历输入数据,找出所有为0的可填区域。
  • 在按一定顺序(可以直接按行遍历整个盘面)标记所有可填区域的可填数字(它所在行所在列及所在宫格已填数字标记为0,可填则标记为1),并按从少到多入队列。
  • 从最少可填数字开始填写,并更新所在行、列及宫格的可填区域的可填数字,直到最后可填区域都填完则返回输出解。

由此看来,此思路适合1只有一解的情况。

4. 【设计的实现过程】:由于本人不太会写类(太菜了,编程没学进去,还是舍友教我怎么写的这段面向过程程序),所以写了3个函数实现,分别是标记可填数字,递归处理求解,输出函数。单元测试没做,而且代码没考虑宫,所以只能解决没有宫的3、5、7阶(有bug……不知道怎么调试了...3阶的不知道有没有😹)仅有一解(多解也只输出一解)数独,而且输入得严格按照作业要求,没有设置容错性分析。

5. 【改进性能】本次作业我写的(应该是舍友和我)代码写完测试后就没优化了,所以性能改进并没有去做。我是按行列顺序遍历深搜的,因为发现按可填数目最少优先求解太麻烦了,不知道怎么实现。

6. 【代码说明】

  • 定义全局变量。
int m, n, ans[9][9];//m-宫格阶级(3~9的整数);n-待解答盘面数目;ans-存放解的数组
bool solved[10];//标记是否得到解
int B = 0;//第几盘
fstream fr, fw;//定义输入输出对象

  • 标记(x,y)格子可填数字——x,y从0到m-1取值
/*标记当前格子可填数字*/
void mark_avai(int x, int y, int(*arr)[9], int *q)
{
	int i(0);
	while (i < m + 1)q[i++] = 1;//q数组初始化为1,表示1~m为可填数字
	for (i = 0; i < m; ++i)
	{
		q[arr[x][i]] = 0;//遍历当前格子所在列,并标记q[列的值]=0,表示当前格子无法填该值
		q[arr[i][y]] = 0;//遍历当前格子所在行,并标记q[行的值]=0,表示当前格子无法填该值
	}
}

  • 定义输出函数。
/*输出函数,方便处理时输出,u为阶数*/
void fileout(int(*arr)[9], int u)
{
	for (int i = 0; i < u; ++i)
	{
		for (int j = 0; j < u; ++j)
			fw << arr[i][j] << " ";//输出一行的值并用空格隔开
		fw << endl;//换行
	}
	fw << endl;//输出完一个盘面的解后换行
}
  • 深搜计算求解。
/*通过递归,求解数独函数,u为阶数*/
void deal(int(*arr)[9], int u, int x, int y)
{
	if (y == u)
	{
		y = 0;
		++x;
	}//如果列号等于阶数则处理下一行
	if (arr[x][y] != 0) //如果当前格子数值不为0
	{
		if (x == u - 1 && y = u - 1) //最后一个格子
		{
                    fileout(arr, m);
		    return;
			
		}//处理完后便退出
		else
		{
			deal(arr, u, x, y + 1);
		} //continue
	}
	int mark[10]; //存放函数mark_avai中q数组的值
	int record = arr[x][y]; //记录传入数组的值
	mark_avai(x, y, arr, mark); //调用函数,获取当前格子(x,y)可填数字
	for (int k = 1; k <= u; ++k)
	{
		if (mark[k] == 0)continue; //如果当前值k不可填则进行k+1判断
		arr[x][y] = k; //mark[k]=1,说明当前格子(x,y)可以为k
		if (x == u - 1 && y == u - 1) //为最后一个格子
			fileout(arr, m), solved[B] = true;//将解输出到文件
		else deal(arr, u, x, y + 1); //非最后一个格子则继续处理下一个格子
		if (solved[B])return; //如果获得解则退出函数
	}
	arr[x][y] = record;//还原传入数组的值
}
  • 命令行处理。(太菜了,查了这么久只知道这样子处理)
int main(int argc,char *argv[])
{
	m = atoi(argv[2]); 
	n = atoi(argv[4]); 
	fr.open(argv[6], ios::in); //读入输入文件
	fw.open(argv[8], ios::out); //打印输出文件
......
}

7. 【构建之法学习心得】

    哎,这么久过去了,书只是浏览了一半左右,并没有认真阅读,直到博客说认真阅读前三章才知道自己已经忘记了这本的具体内容,现在看这本书也宛如第一次看一样,没有丝毫印象。本书最大的特色就是举例了许多对话还告诉读者某个知识点的作用;还有就是语言朴素易理解。大概只记得书中提了代码规范,还好笔者一直都是那样码代码的(虽然没写过多少代码);还有就是结对编程。要说心路历程和收获还是等在用心读读再谈吧。整体上看,本书讲的是如何构建一个·软件及软件开发流程及软件工程理论、技术。差不多就这样子了吧......Bye......下次再见。
PS:

posted on 2019-09-25 17:49  031702112  阅读(366)  评论(0编辑  收藏  举报