軟工我的項目git
https://github.com/Lydia-yang/2017BUAA-SoftwareEngineeringgithub
在剛開始拿到題目的時候,關於生成數獨終局,個人思路是能夠隨機生成數而後選擇適合的數填滿便可獲得,後來經過上網查找一些數獨生成算法,發現能夠經過必定的順序來減小工做量,好比將1到9個數字依次隨機填入3*3的宮格里,或者記錄每次每次嘗試的數避免重複,還有初始化對角線的3個3*3的宮格,或者依次填入1到9等。最後選定了將1到9個數值依次填入3*3的宮格里這種算法,也就是這篇博客的算法。
將數獨分爲9小塊,將1-9按照必定序列填寫1-9小塊,好比先將1填入1號小塊,再填入2號小塊,知道填完9號小塊,再填2與1同樣,遍歷全部數便可獲得一個生成數獨。
至於解數獨,思路與生成數獨差很少,也是回溯,可是是對於每個沒有填的位置試全部可能的數字。算法
實現個人算法,首先,要有一個存儲九宮格的二位數組,出於考慮,我建立了一個數獨類,這個類裏有相應的行列及3*3小塊的重複檢查,以及插入和刪除,因爲我解決數獨和生產數獨用的是不一樣的方法來插入數字的(一個是肯定數字選位置,一個肯定位置選數字),因此有兩種插入的方法,而後就是打印數獨的方法。
在處理命令行中,有判斷-c後面接的是不是正整數的函數,一樣,生成數獨和解數獨都有各自的函數,解數獨是經過文件讀入的,所以也設定了一個處理文件讀入函數,在後面優化的過程當中,又新增了輸出到文件的函數,單元測試主要是將produce和solve這兩個函數測試了一遍。下圖是函數類之間的關係:數組
一開始生成數獨時,幾分鐘都沒出結果,後來通過性能分析,以下圖:
函數
發現是輸出佔了大多數時間,後來作了優化,將輸出結果先輸出到一個字符數組裏,再所有一塊兒輸出,最後的性能分析以下:
post
下面這段代碼是用來解數獨的,其中輸入表明的含義爲:性能
對於每一次執行,將這個空位子插入數字,並標記已經試過的數字,最後完成時輸出,每次回溯時都清空當前位置。單元測試
void solve(sudoku sudo, int x[], int y[],int total, int & count, char *str, int &count_s) { int marked[9] = { 0 };//用來標記數字是否已經選過 int new_count = count; while (true) { int now = sudo.insert(1, x[new_count], y[new_count], marked);//在空位子插入數字 if (now < 0) return; else marked[now-1] = 1; if (new_count == total - 1) {//最後一個 sudo.printsudoku(str, count_s);//打印數獨 return; } count = new_count + 1; solve(sudo, x, y, total, count, str, count_s);//下一個 if (count == total - 1) return; sudo.del(1, x[new_count], y[new_count]); } }
下面這段代碼是用來生成數獨的,其中輸入表明的含義爲:測試
對於每一次執行,將這個數字插入當前3*3小塊空的位置,並標記已經試過的位置,最後完成時輸出,每次回溯時都清空當前位置。優化
void produce(int total, int nums[], int block_num, int & count_total, int count_nums, sudoku s, char *str, int &count_s) { int marked[9] = { 0 };//標記已經試過的位置 int new_block_num, new_count_nums; while (true) { new_block_num = block_num + 1; new_count_nums = count_nums; int now = s.insert(nums[new_count_nums], new_block_num, marked); if (now <0) return; else marked[now] = 1; if (new_block_num == 9) { if (new_count_nums < 8) { new_count_nums=count_nums+1; new_block_num = 0; } else {//填寫至最後一個 count_total++; s.printsudoku(str, count_s);//打印數獨 s.del(0, new_block_num, now); return; } } produce(total, nums, new_block_num, count_total, new_count_nums, s, str, count_s); if (count_total == total) return; s.del(0, new_block_num, now); } }
Psp | personal software progress stages | 預估耗時 | 實際耗時 |
---|---|---|---|
planning | 計劃 | 20 | 30 |
estimate | 估計這個任務須要多少時間 | 10 | 10 |
development | 開發 | 480 | 600 |
analysis | 需求分析 | 10 | 10 |
design spec | 生成設計文檔 | 30 | 35 |
design review | 設計複審 | 0 | 0 |
coding standard | 代碼規範 | 10 | 15 |
design | 具體設計 | 60 | 70 |
coding | 具體編碼 | 240 | 300 |
code review | 代碼複審 | 120 | 130 |
test | 測試 | 240 | 300 |
reporting | 報告 | 20 | 18 |
test report | 測試報告 | 20 | 10 |
size measuring | 計算工做量 | 5 | 3 |
postmortem & process improvement plan | 過後總結,提出過程改進計劃 | 20 | 20 |
合計 | 1285 | 1551 |