【數獨個人專案】關鍵程式碼說明
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
函式程式碼及註釋說明: