数独个人项目-1120161890

(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企业版自动生成:


(5)程序改进及分析

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

数独生成改进:

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

文件输入输出改进:

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

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

下面是性能分析图


(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计划3060
·Estimate·估计这个任务需要多少时间3060
Development开发20702730
·Analysis·需求分析(包括学习新技术)180360
·Design Spec·生成设计文档6090
·Design Review·设计复审(和同事审核设计文档)6060
·Coding Standard·代码规范(为目前的开发制定合适的规范)3030
·Design·具体设计120120
·Coding·具体编码10801440
·Code Review·代码复审360360
·Test·测试(自我测试,修改代码,提交修改)180270
Reporting报告300300
·Test Report·测试报告180180
·Size Measurement·计算工作量6060
·Postmortem&Process Improvement Plan·事后总结,并提出过程改进计划6060
 合计24003090
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值