(1)https://github.com/Agazelle98/MY_SUDOKU

(2)PSP表格(估计时间,见文章末尾)

(3)解题思路描述

数独生成

在拿到题目的之后,先了解了数独的游戏规则和求解数独的各种方法,发现只要第一行给出了确定的数字序列,那么其他八行能够通过第一行的变换得到一个完整的数独,首先将整个大九宫格分为九个3*3的小九宫格,然后再每个小九宫格中填入数字,检查数字并进行回溯,这里我选用了随机数生成法。

需求分析:

命令行格式:sudoku.exe -c N

1<=N<=1000000

数独不重复

数独左上角首数字固定。

可行性分析:我的首数字为(9+0)%9+1=1,只需要随机生成其他八个数字即可,这样有8=40320种情况,经过回溯变换再生成其他八行,完全可以生成超过1e6个不重复的数独。

求解数独

在数独生成的基础上加上判断,按顺序把数字填入小九宫格,如果该数字没有合适的位置,则将上一个填入的数字进行替换,直到找到一个能够完全填满的方式。

需求分析:

命令行格式:sudoku.exe -s absolute_path_of_puzzlele

0代表空,每个题目只要输出一个可行解即可

(4)设计实现过程

首个版本由于一开始没有找到解题简便方法,在生成数独的过程中是完全随机的,也就是说,在回溯的思路下,希望能够给出数独终局更多的随机性,但是没有考虑给出随机数字之后的检验问题,事实很快就告诉我这种方法不行,于是第一个版本被pass掉了。

之后通过上网查找方法和其他同学给的建议,放弃了完全随机的思想,而是小范围随机生成数字,通过规律变换生成最终数独,这是一个讨巧的办法,回溯的具体过程用到rowcolumn, square三个9 * 9的数组做标记,记为1,记录每一行、列、九宫格中已使用的数字在初始数组中的index。一个循环结束后回退时把标记抹去。在求解数独时也是用了相同的方法。

下面是函数关系图,由vs企业版自动生成:

数独个人项目-1120161890

(5)程序改进及分析

改进的话在设计实现过程中提及过,主要是将完全随机改为首行随机加回溯变换。

数独生成改进:

左上角为1,先将9个1放入合法位置中,然后随机产生初始行,求解数独,然后由初始数独映射,每个初始数独能够生成8!个数独终局,由于9个1的位置不同,所以产生的初始数独不同。

文件输入输出改进:

将所有终局数独存在一个长字符串中一次性输出。

用ifstream,stringstream,string一次将文件内容读入。

下面是性能分析图

数独个人项目-1120161890

数独个人项目-1120161890

(6)代码说明

int **CreateArray();.....................................................................................................创建数独棋盘

int *CreateSet();..................................................................................................创建数组并初始化

void DeleteArray();..............................................................................................................删除数组

int FindSudokus();........................................................................................生成左上角第一格数独

int GenerateSudokus();...........................................................................................对数独进行变换

int* InitSet();...............................................................................................................生成数独首行

int SolvePuzzles();...............................................................................................................标记行列

void SudokuOutput();.............................................................................将结果存入outputStr数组

int PuzzleInput();..................................................................................................-s情况下棋盘输入

void print();.........................................................................................................................打印棋盘

int Transfer();.......................................................................................................将字符转换为数字

(7)PSP表格(实际时间,见文章末尾)

(8)总结

本次项目从清明节假期开始做,所以起点比别的同学稍晚了一些。vs2017GitHub都是第一次使用,在学习软件运用的过程中花费了好多的时间,之前的编程课都是用的dev-cppcodeblocks,所以在第一次使用vs时连创建项目都需要摸索,向同学请教后逐渐熟悉了vs的使用方法。在进行主项目编码的过程中,参考了网上给出的生成数独的方法,和一些其他同学的建议,使用的是随机数生成法,然后通过回溯变换生成数独终局,由于能力有限,优化也只做了文件的输出部分和数组优化。通过这次的个人项目经历,真正发现了自己与其他同学的差距,也是对自己学习能力和文档能力的一个提升,希望能为以后的项目做一个铺垫。

附录:PSP表格
PSP2.1

Personal Software Process Stages

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

相关文章: