软件工程实践第二次作业

1)Github项目地址:
the address of github

2)PSP 2.1表格:

PSP

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

3)解决思路描述:

  • ①首先,任务描述为:

用程序随机构造出N个已解答的数独棋盘。(根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。)

根据这个条件的话感觉很简单,即构造一个9*9数组,并根据对应的三个条件确定每个位置上要填的数字。
  • ②因为有新增要求如下

2017.9.4 新增要求] 在生成数独矩阵时,左上角的第一个数为:(学号后两位相加)% 9 + 1

所以改变思路,先满足第一行第一个数,再去随机生成其他数字。

4)设计实现过程:

  • ①初始化一个9*9数组,每个位置都为0,[0][0]位置置为要求的数字。
  • ②先随机生成第一行。
  • ③从第二行第一个位置开始迭代,根据对应的三个条件确定数字。
  • ④未找到满足条件的数字时,回溯到前一个位置并重新填数。(重点)

5)代码说明:

  • ①随机生成第一行及判断输入
int main(int argc,char* argv[])
{
	string ss = argv[2];
	int len = ss.length();
	for (int i = 0; i < len;i++) {
		if (ss[i]<'0' || ss[i]>'9') {
			printf("error input");
			return 0;
		}
		else {
			N = N * 10 + ss[i] - '0';
		}
	}
	freopen("sudoku.txt","w",stdout);
	srand((unsigned)time(NULL));
	sudoku[0][0] = 9;
	for (int i = 1; i<9; i++)
	{
		sudoku[0][i] = i;
	}
	random_shuffle(&(sudoku[0][1]), &(sudoku[0][8]));
	produce_sudoku(1, 0, 1);
	return 0;
}
  • ②判断是否满足条件
bool judge(int line,int column,int a,int sudoku[9][9])
{
	int x,y;
	for(int i=0; i<9; i++)//行判断 
	{
		if(sudoku[line][i]==a)
		{
			return false;
		}
	}
	for(int i=0; i<9; i++)//列判断 
	{
		if(sudoku[i][column]==a)
		{
			return false;
		}
	}
	x = (line/3)*3;
	y = (column/3)*3;
	for(int i=x; i<x+3; i++)//九宫格判断 
	{
		for(int j=y; j<y+3; j++)
		{
			if(sudoku[i][j]==a)
			{
				return false;
			}
		}
	}
	return true;
}
  • ③依次判断及回溯
void produce_sudoku(int i,int j,int z)
{
	if (j < 0)
	{
		i--;
		j=0;
	}
	if(j>8)//换行 
	{
		i++;
		j=0;
	}
	if(i==9&&j==0)
	{
		for(int k=0; k<9; k++)
		{
			for(int l=0; l<9; l++)
			{
				cout << sudoku[k][l] << " ";
			}
			cout << endl;
		}
		cout<<endl;
		if (--N <= 0)
		{
			exit(0);
		}
	}
	else if (i < 9) //z的作用为防止生成重复矩阵 
	{
		for(int kk=1;kk<9;kk++){
		int n = (z++)%9 + 1;
		if(judge(i,j,n,sudoku))
		{
			sudoku[i][j] = n;
			produce_sudoku(i,j+1,z);//----回溯 ---- 
			sudoku[i][j] =0;//----回溯 ---- 
		}
	}
	} 
}

6)测试运行(DEV)

  • ①N=1000:

  • ②N=10000:

7)效能分析(100W):

报告分析:
时长主要耗在produce_sudoku函数中的回溯过程,代码执行效率和算法有待提高。

posted @ 2017-09-10 19:21  HKSun  阅读(147)  评论(2编辑  收藏  举报