软件工程基础——个人项目

一、项目地址

代码托管在了GitHub上,附上链接如下:

GitHub链接

二、PSP

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

三、需求分析

生成终局

输入参数:sudoku.exe -c 20(生成数独终局的数目)	
a. 生成指定数量的数独终局
b. 能处理非法参数
c. 左上角第一个数固定(9+7)%9+1=8
d. 输入范围限制在1~1000,要求在60s内给出结果
e. 结果输出到文件sudoku.txt中并要求可被覆盖

求解数独

输入参数sudoku.exe -s absolute_path_puzzlefile
a. 从指定文件中读取数据,并将结果输出到指定文件中
b. 保证文件中数独格式正确
c. 结果的格式要与生成终局的格式相同

四、解题思路描述

项目包括生成指定个数的数独终局以及求解给定的数独终局,因此要弄懂数独生成算法以及求解数独的算法。首先想到的解决办法就是回溯法,对单个数字进行填充,如果的得到的结果不满足条件的话,我们就回溯到上一层,知道求出正解。在搜索引擎输入求解数独可以得知Dancing Links算法是求解数独常用的算法,算法原理比较容易理解,它实际上是一种数据结构(交叉十字循环双向链)。由于解决精确覆盖问题的X算法中需要频繁用到移除、恢复操作,而在这种结构下,进行这两种操作的效率极高。

跳跃的舞者,舞蹈链算法(Dancing Links)------求解精确覆盖问题

五、设计实现过程

首先分析出程序流程如下:

Created with Raphaël 2.2.0 开始 输入指令 分析指令 求解数独 输出数据 结束 生成终局 yes no

列出需要的函数如下:

extern int Read(char str[]); //读取参数并判断参数是否合法
extern int Random_Init(int Num[]); //随机初始化第一行
extern int Judge_Sudoku(int s, int x, int y, int num); //判断数独终局知否合法
extern int Fill_Sudoku(int s, int x, int y); //填充数独
extern int Creat_Sudoku(int Sodoku_Num); //创建数独终局
extern int Solve_Sudoku(char File[]); //解数独残局

五、性能改进

对于第一个可执行的版本,对其进行性能测评,结果如下图所示:

性能分析报告
具体函数模块

可见函数输出占据了大量时间,于是我将输出改为putchar之后,大量减少了输出时间。

六、代码说明

Fill_Sudoku这一部分函数在很多地方都有调用,将此部分代码拎出来作为重点。

int Fill_Sudoku(int s, int x, int y)				//填充函数
{    
	int Trace_back = Board[s][x][y];
	int next_x = x + (y + 1) / 9;					//定义下一方格横坐标
	int	next_y = (y + 1) % 9;						//定义下一方格坐标
	
	if (x > 8)
		return 1;
		
	if (Board[s][x][y]) 
	{
		if (Fill_Sudoku(s, next_x, next_y))
			return 1;
	}
	else 
	{	
		int i;
		for (i = 0; i < 9; i++)						//判断合法性
		{
			int Try_Num = Try_List[i];
			if (Judge_Sudoku(s, x, y, Try_Num))
			{
				Board[s][x][y] = Try_Num;
				if (Fill_Sudoku(s, next_x, next_y))
					return 1;
			}
		}
	}

	Board[s][x][y] = Trace_back;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40270187/article/details/84575048