GitHub 地址

软工实践第二次作业链接

因为git和vs以前做计算器的时候用过 使用起来还是蛮熟悉的。

解题思路

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

简单的了解下数独就是每一行,每一列,每一小九宫格的数字均为1-9,且每个数字只出现一次不重复。

故这题就是用一个数组flag标记该位置是否可填数字,如果可填,通过get_next_num(int,int,int)找到可行数字并且填入到Sudoku[][]中去 ,然后进入下一层递归,如果获取不了就返回上一层递归。

解法No.1:刚开始我是想每次标记的时候都把整行,整列,以及整个小九宫格遍历一遍,寻找是否该数字可用,觉得这样子很耗时间。

解法No.2:现在我们在算法中用了 row_mark[][] col_mark[][] J_Gong_mark[][]三个数组来标记该行数字是否用过,该列数字是否用过,以及该小九宫格是否用过这数字。方便后面检查。
比如说某一行的某个数字用过就用数组 row_mark [第几行][哪一个数字] = 1 做标记
再比如说某一列的某个数字用过就用数组col_mark[第几列][哪一个数字] = 1 做标记
某一小九宫格的某个数字用过就用数组J_Gong_mark[第几个小九宫格][哪一个数字] = 1 做标记 //PS: 小九宫格位置计算 3*(行/3)+(列/3)
这样子我们可以减少查询次数,节省了一大部分时间。
flag[][]数组,它用来标记,哪些位置是可以填数的,换句话来说,哪些位置,在初始状态是空的。初始完后,我们用回溯法,从第一个位置开始寻找,从三个数组中找交集即(row_mark col_mark J_Gong_mark ) 也就是说这三个数组都没标记这个数字 说明该数字是可以用的,如果当前数可用,就进入下一层的递归,直到到达最后一个格子。

还有本算法可以通过递归找到你所需要填的的几个数独棋盘。由于我们每次寻找的都是可用数字,不用判断当前数是否符合规则。

代码

  
//进行回溯 加 遍历
void sudokulib::backdate(int x, int y) {
	if (y == 9) x++, y = 0;
	while (flag[x][y] && x <= 8) {
		y++;
		if (y == 9) {
			x++, y = 0;
		}
	}
	if (x > 8) {
		print();
		if (++cnt == N) {
			exit(-1);
		}
	}
	while ((sudoku_tmp[x][y] = get_next_num(x, y, sudoku_tmp[x][y] + 1)) != -1) {
		row_mark[x][sudoku_tmp[x][y]] = 1;
		col_mark[y][sudoku_tmp[x][y]] = 1;
		J_Gong_mark[3 * (x / 3) + (y / 3)][sudoku_tmp[x][y]] = 1;   //说明该数字可以用 
		backdate(x, y + 1);
		row_mark[x][sudoku_tmp[x][y]] = 0;
		col_mark[y][sudoku_tmp[x][y]] = 0;
		J_Gong_mark[3 * (x / 3) + (y / 3)][sudoku_tmp[x][y]] = 0;   //说明该数字不能用  还原到前一个状态 
	}
}


运行结果

性能测试

以下是我跑100W数据的性能分析:


从图中可以看出该程序还是挺慢的 !!跑100W数据都得6分多钟。感觉要改进的话就应该用数字字符,可能跑的速度会快一点。

单元测试

这一块还不怎么懂,看百度一些资料1 资料2自己也尝试了,一直调试不出结果。Orz......

简简单单的记录

.初次记录 有点乱 也不知道什么作用 希望后面能明白 迷迷糊糊....

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

心得体会

做这个任务的时候发现已经快开学了,所以自己也提前回学校来学习如何处理这个任务,也去看了很多资料,看了很多前辈们的做法和优化。在这个过程中最让人头疼的是使用vs做性能测试和单元测试,到现在为止单元测试还是没搞明白,但在这过程中还是学会了蛮多的,至少现在看到了vs的强大(可能还有更强大的功能需要我们在这过程中慢慢去发觉),我觉得这才刚刚开始,接下来会更好玩........

posted on 2017-09-10 17:40  suefen  阅读(189)  评论(1编辑  收藏  举报