github地址:https://github.com/Duuang/Project-Sudoku
关键代码说明
目录
二、ConsoleParameter类:ConsoleParameter.cpp
三、SudokuSolution类: SudokuSolution.cpp
四、SudokuPuzzle类,SudokuPuzzle.cpp
一、main.cpp
int main()
先看main()函数,先用Consolepatameter类对象,获取控制台参数,然后判断参数是合法的-c/合法的-s/非法的参数
如果合法-c,则新建SudokuSolution类对象,调用Generate生成数独
如果合法-s,则新建SudokuPuzzle类对象,调用SolveAll解数独,并输出可解的和无解的个数(还考虑了文件是否成功打开)
二、ConsoleParameter类:ConsoleParameter.cpp
构造函数
ExtractCommand()
读取控制台的参数,并判断第一个参数是-c还是-s还是其他,更新成员变量command的值
ExtractOperationCode()
若是-c,则先判断字符串长度是否>8,然后判断是否字符串全由数字组成,最后用sscanf_s()将字符串转换为数字,更新operationcode_c,返回0,否则返回-1
若是-s,则更新operationcode_s,返回0
其他值,返回-1
三、SudokuSolution类: SudokuSolution.cpp
GenerateBasicPuzzle()
生成25个基础数独(经过1~9排列也不能重复的那种),为了之后的8!×25 的100万个数独做准备
第一行固定123456789
注释的数独即为第一个基础数独,在这个基础上,第2行中的456内和789内可以进行全排列,即为不同的数独
所以把这6*6=36种排列,用两个sequence456[6][3]表示了,方便之后调用
剩下的就是按照规则生成数独了,按后三行为前3行右移1列生成即可
Generate()
用来生成指定数量的数独
先调用GenerateBasicPuzzle(),然后生成一个1~9的序列,对每一个序列,将basic puzzle中的值根据1~9序列替换,即得到了新数独。
然后将数独写入outputstring缓冲区,一个数独的数据全部写入缓冲区后,将缓冲区数据写入到文件
写缓冲区的过程是用的指针指示当前位置,一个个字符写,放弃了用strcat()函数
变量定义:
根据序列替换数独:
向缓冲区写入数独数据:
写入文件:
四、SudokuPuzzle类,SudokuPuzzle.cpp
SolveAll()
反复调用GetNextPuzzle()和SolveCurrentPuzzle()求解
GetNextPuzzle()
从文件中读取下一个数独题,成功返回0,失败-1
SolveCurrentPuzzle()
调用dfs_solve(),解当前puzzle中存放的数独
在解数独前,先判断,已经给的数独题中有没有本来就冲突的地方
数独题目本身不矛盾,则解数独,并输出到文件
...
dfs_solve(int depth)
调用时depth取1,回溯搜索所有解
涉及回溯的几行关键代码:
solution[depth - 1] = i; //记录当前节点解
puzzle[position_of_blanks[depth - 1][0]][position_of_blanks[depth - 1][1]] = i;//更改puzzle
dfs_solve(depth + 1); //递归回溯
puzzle[position_of_blanks[depth - 1][0]][position_of_blanks[depth - 1][1]] = 0;//还原puzzle
函数代码及注释说明: