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

Githubsudoku

项目相关要求

利用程序随机构造出N个已解答的数独棋盘 。

输入

数独棋盘题目个数N(N在0和1000000之间)

输出

随机生成N个不重复的已解答完毕的数独棋盘,并输出到sudoku.txt中。在生成数独矩阵时,左上角的第一个数为:(学号后两位相加)% 9 + 1。

思路与代码

一暑假没碰过代码的我,在暑假结束前一周看到了这个作业题目,脑子里想起来的就是大一的时候敲得八皇后和马遍历的题目,比较类似,都是关于递归回溯的算法。大致思路就是给每个格子试不同的数,找到符合条件的填下,如果不可以的就回到前一个,换一个数再试试,不行再回溯,于是有了下面的代码:

int count=0;//统计输出了多少数独 
void sudoku(int i,int j)
{
	for(int x=1;x<=9;x++)//给每个格子都试9个数 
	{
		if(check(i,j,x)==1)//如果可以 
		{
			board[i][j]=x;//就赋值 
			if(i==8&&j==8)//如果填满了,就输出 
			{
				print();
				count++;
				if(count>=N) exit(-1);
				return;//输出还没到N个,就继续返回试其他数 
			}
			if(j==8)//如果当前位置是某一行最后一个,就跳到下一行第一个 
			{
				sudoku(i+1,0);
			}
			else//不然就跳到下一个 
			{
				sudoku(i,j+1);
			}
		}
	}
	board[i][j]=0;
	return ;//这个格子没有一个数符合,就返回上一个格子 
} 

下面是判断这个格子是否可以这个数的check函数:

int check(int row,int col,int num)//判断是否能放 
{
	for(int i=0;i<9;i++)//判断列有没相同的 
	{
		if(board[i][col]==num)return 0;
	}
	for(int j=0;j<9;j++)//判断行有没相同的 
	{
		if(board[row][j]==num)return 0;
	}
	int x=row/3,y=col/3;
	x=3*x;
	y=3*y;
	for(int i=0;i<3;i++)//检查小九宫格 
	{
		for(int j=0;j<3;j++)
		{
			if(board[x+i][y+j]==num)return 0;
		}
	}
	return 1;
}

生成100W个数独大概要52秒左右
生成的结果输出到sudoku.txt

性能分析

用VS自带的性能分析器进行分析,测试的生成的数独为10W个:


PSP

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

反思与总结

这次代码虽然思路简单,但是递归实现起来理解的意思确实很复杂,因为好久没敲这类题,已经忘记了当时如何理解递归。经过一番痛苦挣扎(把之前八皇后和马遍历的代码翻出来温习了一下),总算有点想明白,递归就是层层递归,就像一颗树一样,从根节点递归到子节点,子节点行不通,return会根节点从旁路走。其实我还想了一种方法(其实是网上看到的),就是把九宫格分成九个独立的宫,因为每个宫都会有1-9九个数字,所以就按数字来放,比如先把1排进每个宫,接着放2,以此类推,而且在放头尾两个数的时候完全不用回溯,我觉得应该会减少代码运行复杂度,我也尝试的敲了下,奈何学艺不精没有成功,于是就选了这种普通的方法。这很反映了我现在的代码能力很弱,需要加强咯。

posted @ 2017-09-10 21:04  wujunyi  阅读(141)  评论(1编辑  收藏  举报