第二次作业——个人项目实战:数独
第二次作业——个人项目实战:数独
运行环境:	windows10
编程IDE:		Visual Studio 2017 社区版
编程语言: C++
Github地址:传送门
1)项目需求
利用程序随机构造出N个已解答的数独棋盘。
输入: 数独棋盘题目个数N(0< N<=1000000)
输出:随机生成N个 不重复 的 已解答完毕的 数独棋盘,并输出到sudoku.txt中
2)解题思路
首先我想到的是本题中的随机性,用C++中的随机函数rand()来产生随机数。在一开始先利用随机数生成左上角的第一个宫格,在此过程中只需要判断第一个宫格是否数独冲突。在接下去的宫格生成过程中,需要每个数的宫格检查、行检查、列检查。而在后续的宫格生成过程中可能会存在无解的情况,这时候就需要回溯重来。
由于左上第一个数字是固定的,则第一个宫格的随机排列组合有8!=40320种,若再加上其他行列的变化后会有几何数级增长的可能性,经过了解,数独的可能有6,670,903,752,021,072,936,960种组合。其他宫格中每个数字的生成有9种可能(1~9),若试完这些可能仍然无法填入宫格则为无解,需要重新再来。
3)设计实现
采用一个动态的二维数组来表示数独棋盘(9×9),初始化为0表示未填入。设计列检查、行检查、宫检查的函数以及生成宫格的函数和打印函数(检查用)。输入需要生成棋盘的个数N后,开始初始化棋盘,首先用随机数生成一个满足要求的第一宫格,接下去的八个宫格均同样方法(若无解回到第一步生成宫格开始),为提高效率,若重试次数过多(这里限制为100次),则重新生成整个棋盘。(简单粗暴的方法)
4)代码说明
//行检查(列检查同理)
bool Sudoku_Row(int arr[9][9],int row, int num)
{
	bool flag = false;
	for (int i = 0; i < 9; i++)
	{
		if (arr[row][i] == num) 
		{
			flag = true;
			break;
		}
	}
	return flag;
}
//宫检查
bool Sudoku_Square(int arr[9][9],int row, int col, int num)
{
	bool flag = false;  //冲突标志
	int Square_Row = (row / 3) * 3;
	int Square_Col = (col / 3) * 3;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (arr[Square_Row + i][Square_Col + j] == num)
			{
				flag = true;
				break;
			}
		}
	}
	return flag;
}
//生成宫格
bool makeSquare(int arr[9][9],int num)
{
	int square_row = (num / 3) * 3;
	int square_col = (num % 3) * 3;
	int x, y;
	int temp;
	if (num == 0)  //第一个宫格
	{
		for (int i = 1; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp = Random(8) + 2;//生成2~9的随机数
			if (!Sudoku_Square(arr, x, y, temp))
			{
				arr[x][y] = temp;
			}
			else i--;
		}
	}
	else  //其他宫格
	{
		int try_count = 0;
		temp = Random(9)+1;////生成1~9的随机数
		for (int i = 0; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp++;
			temp = temp % 10;//循环随机数在1~9范围内
			if (!Sudoku_Square(arr, x, y, temp) && !Sudoku_Col(arr, y, temp) && !Sudoku_Row(arr, x, temp)&&temp!=0)
			{
				arr[x][y] = temp;
				try_count = 0;
			}
			else
			{
				i--;
				try_count++;
			}
			if (try_count > 10)
			{
				return false;
				break;
			}//若所有可能试完则返回无解
		}
	}
	return true;//有解
}
5)测试运行



N=10000
如图所示 输出和宫格生成占用的时间最多,在这方面还有很多需要改善。
由于项目开始时间太晚,只能先完成这些部分了,后续再完善(有生之年)
6)关于执行力与泛泛而谈
执行力是一个种将意愿转化为实际结果的能力,也就是与办事能力、工作效率相挂钩。若是三分钟热度,往往只是停留在空想阶段,容易泛泛而谈,一旦碰壁就放弃。兴趣和热情很重要,方式方法也是另一面手心,热情毕竟是有限的,提高执行力能看到实际的结果,也比较有信心把这件事做下去。
PSP
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) | 
|---|---|---|---|
| Planning | 计划 | 600 | 800 | 
| · Estimate | · 估计这个任务需要多少时间 | 30 | 20 | 
| Development | 开发 | 600 | 800 | 
| · Analysis | · 需求分析 (包括学习新技术) | 120 | 60 | 
| · Design Spec | · 生成设计文档 | 100 | 60 | 
| · Design Review | · 设计复审 (和同事审核设计文档) | 60 | 30 | 
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 100 | 0 | 
| · Design | · 具体设计 | 100 | 100 | 
| · Coding | · 具体编码 | 600 | 800 | 
| · Code Review | · 代码复审 | 100 | 150 | 
| · Test | · 测试(自我测试,修改代码,提交修改) | 100 | 150 | 
| Reporting | 报告 | 150 | 250 | 
| · Test Report | · 测试报告 | 60 | 30 | 
| · Size Measurement | · 计算工作量 | 30 | 25 | 
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 10 | 
| 合计 | 2180 | 2485 | 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号