高級軟件工程-第二次作業-數獨
阿新 • • 發佈:2017-10-09
exchange 生成 數獨 技術 standard .cn 所在 作業 test
https://github.com/mengyitf/sudoku
1. github地址
2. 解題思路
數獨的要求是在9*9宮格中每一行,每一列,每一個3*3的小九宮格都是由1到9不重復的數字組成的。
其中可以看到:
(1)行交換或者列交換的時候,行和列的值不會改變。例如,我將第1列和第3列交換。
可以發現列交換的時候,列的值完全沒有改變,行的值順序變了,但是值依舊是1到9中沒有重復的數。只要保證在列交換和行交換的時候,對應的3*3小九宮格不會格式錯誤就行。
怎麽樣做才能做到這點呢?觀察可以發現,在小九宮格中行和行交換,列和列交換,小九宮格是不會異常的。直接進行大九宮格所在的行或者列進行交換也是能夠得到不變的格式。
(2)在一個數獨矩陣中,全部相同數值交換也是不會破壞數獨的格式的。例如,我將所有的4和2交換。
可以發現2和4的位置雖然變了,但是整體的結構是沒有變化的。
3. 設計實現
(1)構建一個可行的數獨
(2)產生1到9不重復的任意隨機數與數獨棋盤中從1到9的數一一替換。例如第一次產生隨機數6,則所有的6與1交換。
(3)每個數都交換之後,進行小九宮格行或列交換。
4. 代碼說明
1 void value_exchange(int i,int c){ 2 int j, p; 3 for (j = 0; j < 9; ++j){ 4 for (p = 0; p < 9; ++p){ 5 if(sudoku[j][p]==i){ 6 sudoku[j][p] = c; 7 }else if(sudoku[j][p]==c){ 8 sudoku[j][p] = i; 9 } 10 } 11 } 12 }
value_exchange()是進行值交換,其中i表示循環中1到9中的一個值,c表示1到9中的不重復的隨機值。
1 void row_exchange(int i,intu){ 2 int j,p,t,c,r1,r2; 3 r1 = (i-1)/3*3; 4 r2 = (i-1)%3*3; 5 for (j = 1; j < 3; ++j){ 6 c = (j+u)%3; 7 for (p = 0; p < 9; ++p){ 8 t = sudoku[r1+j][p]; 9 sudoku[r1+j][p] = sudoku[r1+c][p]; 10 sudoku[r1+c][p] = t; 11 } 12 u = ++u % 3; 13 if(u=0)u=1; 14 c = (j+u)%3; 15 for (p = 0; p < 9; ++p){ 16 t = sudoku[p][r2+j]; 17 sudoku[p][r2+j] = sudoku[p][r2+c]; 18 sudoku[p][r2+c] = t; 19 } 20 } 21 }
row_exchange()是小九宮格內行列交換的操作,其中i表示循環中的值,行或列交換的偏移量。
k = 511; for (i = 1; i < 10; ){ u = rand() % 2 + 1; //位置交換 c = rand() % 9 + 1; //交換因子 if((k>>(c-1))%2>0){ value_exchange(i, c); row_exchange(i, u); k = k - (1<<(c-1)); ++i; } }
在這個代碼中由c產生隨機值,k等於511,511表示二進制中九個1,使用移位運算來判斷是否重復產生值。沒有重復將k中對應位的1設置為0,否則繼續產生隨機數。例如產生隨機數5,則111111111設置為111101111。
5. 運行測試
控制臺運行mian -c 3
6. 性能分析
當生成數獨棋盤1000個時
當生成數獨棋盤為4000時
當生成數獨棋盤數為10000時
7. PSP
PSP | Personal Software Process Stages | 實際耗時(分鐘) |
Planning | 計劃 | 30 |
Estimate | 估計這個任務需要多少時間 | 30 |
Development | 開發 | 300 |
Analysis | 需求分析 (包括學習新技術) | 100 |
Design Spec | 生成設計文檔 | 30 |
Design Review | 設計復審 (和同事審核設計文檔) | 20 |
Coding Standard | 代碼規範 (為目前的開發制定合適的規範) | 30 |
Design | 具體設計 | 30 |
Coding | 具體編碼 | 120 |
Code Review | 代碼復審 | 30 |
Test | 測試(自我測試,修改代碼,提交修改) | 20 |
Reporting | 報告 | 30 |
Test Report | 測試報告 | 20 |
Size Measurement | 計算工作量 | 30 |
Postmortem & Process Improvement Plan | 事後總結, 並提出過程改進計劃 | 30 |
合計 | 850 |
高級軟件工程-第二次作業-數獨