Github鏈接:https://github.com/zora02/object-oriented/tree/master/BIN
https://github.com/zora02/object-oriented/blob/master/shuduku.cpphtml
利用程序隨機構造出N個已解答的數獨棋盤 。ios
輸入c++
數獨棋盤題目個數N(0< N <= 1000000)git
輸出github
隨機生成N個不重複的已解答完畢的數獨棋盤,並輸出到sudoku.txt中。c#
構造數獨:最開始想經過隨機數先生成一個九宮格,再刪除掉裏面的重複數,再求解。但是這個方法我寫出來之後常常進入死循環,試了不少辦法,就是改不出bug(╥﹏╥),並且這個代碼效率比較慢。後來我去百度知道了回溯法構造數獨,以爲這個方法效率高些,並學習了來使用。windows
參考代碼:http://blog.csdn.net/hustspy1990/article/details/7464698xcode
(其實看了這個代碼之後,我深受影響,把本身的設想都推翻了,總以爲本身的方法不太好,想學習這個方法。我認真理解了這個方法之後,就用了,可是代碼寫出來就差很少了,我挺懼怕被判抄襲的,我不知道學習了這個方法用起來,算不算抄襲(´・_・`))dom
生成隨機數:在生成隨機數的時候,最開始我不會使用隨機數,就去查資料:函數
http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html
rand()產生的隨機數在每次運行的時候都是與上一次相同的。若要不一樣,用函數srand()初始化它。能夠利用srand((unsigned int)(time(NULL))的方法,產生不一樣的隨機數種子,由於每一次運行程序的時間是不一樣的。
由於是生成多個隨機數獨,因此我把構造數獨的函數放到循環裏去生成,結果發現每次產生的數獨都同樣,最開始覺得是隨機數的隨機性沒有那麼強,但是這與資料裏說的用time初始化種子每次都不同相矛盾。我就去嘗試把隨機生成的不完整數獨輸出查看,發現每次輸出的數獨並不同。覺得本身構造方法錯了,但是我以爲這個方法不影響不一樣數獨的隨機性。
去查了資料發現:
應用在一個FOR循環中,取到的多個隨機值就基本相同的緣由以下:
用系統時間作隨機種子並不保險,若是應用程序在一個較快的計算機上運行,則該計算機的系統時鐘可能沒有時間在此構造函數的調用之間進行更改,Random 的不一樣實例的種子值
原來是srand()不能放在for循環內,應該放到外面初始化種子纔不會重複。中途還想要用guid生成隨機數,可是好像在c#中適用,c++用的不多,不太方便的樣子。
使用命令行編譯:因爲我沒有windows系統的電腦,本身電腦裝雙系統,又裝vs的話系統很容易崩掉,慘痛教訓,因此個人IDE是Xcode。做業裏要求的用命令行進行編譯,我是借用別人的電腦進行嘗試和修改的,可是好像不太成功,-c能夠編譯,可是好像沒法識別後面的數,數目要輸入兩遍(T_T),查了好久資料也不知道怎麼解決。
檢查九宮格內數是否合法:利用bool函數判斷
bool shudu_check(int shudu[][9],int x,int y) { int i,j; int temp = shudu[x][y]; //檢驗同一行數是否有重複 for(i=0;i<9;i++) { if(i!=x && shudu[i][y] == temp) return false; } //檢驗同一列數是否有重複 for(j=0;j<9;j++) { if(j!=y && shudu[x][j] == temp) return false; } //檢驗小九宮格內數是否有重複 int x0=(x/3)*3; int y0=(y/3)*3; //(x0,y0)是(x,y)所屬小九宮格內左上角第一格的座標 for (i = x0; i<x0+3; i++) { for(j=y0; j<y0+3; j++) { if(i!=x && j!=y && shudu[i][j]==temp) return false; } } return true; }
構造數獨:回溯法,基本思想就是深度優先搜索(DFS),對不完整隨機數獨每一個數進行檢查,數知足條件就檢查下一個數,不知足條件就退回,並把數置0,從新賦予知足條件的數。
void shudu_generate(int flag) { int shudu[9][9]={0}; int x, y; shudu[0][0]=4; //生成隨機數賦值給九宮格 for(int i=0; i<9; i++) { int a=rand()%81; if(a/9!=0 || a%9!=0) //限制shudu[0][0]爲固定值 shudu[a/9][a%9]=i+1; } //回溯法構造數獨 int t=1; while(flag==1) { x=t/9; y=t%9; while(flag==1) { shudu[x][y]++; if(shudu[x][y]>9) //回溯,把數置零 { shudu[x][y]=0; t--;break; } else if(shudu_check(shudu,x,y)==true)//合法,檢查下一個數 { t++;break; } } if(t==81) { shudu_print(shudu); cout<<endl; flag=0; } } return; }
(先在這裏解釋一下,我代碼和博客的編寫都是在Mac系統下完成的,只是借用別人的windows電腦編譯完成,生成exe文件提交,因此我測試運行與性能分析都是由Xcode完成,請見諒T_T)
測試結果截屏
(因爲種種緣由我借用的windows電腦裏的vs軟件沒法生成性能分析報告,好像是缺乏一個項目,可是我下了sp1,仍是不行,因此我嘗試着用xcode,可是我好像不太會用)
其實我沒有搞懂性能分析報告,看得有點迷,也不知道該如何下手去修改代碼(>_<)
也沒有在網上找到一些教程,更多關於xcode性能測試的教程都是關於ios開發的
只是找到這篇http://blog.csdn.net/ggghub/article/details/50325637 多是本身知識儲備太少,我基本看不太懂這個性能分析該如何使用,因此我沒有去優化代碼,真的不知道怎麼改(T_T)可是我試着去看看運行比較大數據的時候CPU的狀況,好像不太樂觀??CPU佔比有點大是這個意思嗎?我以爲可能仍是構造數獨函數消耗最大。
這是剛開始測試num=1000的狀況:
PSP2.1 | Personal Software Process Stages | 預估耗時 | 實際耗時 |
---|---|---|---|
Planning | 計劃 | 1.5h | 3-4h |
· Estimate | · 估計這個任務須要多少時間 | 2days | 3days |
Development | 開發 | 2h | 3h |
· Analysis | · 需求分析 (包括學習新技術) | 3-4h | 3-4h |
· Design Spec | · 生成設計文檔 | 1h | 2-3h |
· Design Review | · 設計複審 (和同事審覈設計文檔) | 30mins | 1h |
· Coding Standard | · 代碼規範 (爲目前的開發制定合適的規範) | 30mins | 30mins |
· Design | · 具體設計 | 1h | 1h |
· Coding | · 具體編碼 | 2h | 3h |
· Code Review | · 代碼複審 | 30mins | 1h |
· Test | · 測試(自我測試,修改代碼,提交修改) | 1h | 2h |
Reporting | 報告 | 1h | 1.5h |
· Test Report | · 測試報告 | 10mins | 1h |
· Size Measurement | · 計算工做量 | - | - |
· Postmortem & Process Improvement Plan | · 過後總結, 並提出過程改進計劃 | 1h | 1.5h |
合計 |
因爲一些事情,完成做業的時間跨度蠻大的,因此沒有認真的計時,我只是寫了個大概的時間,沒有辦法具體合計出來,請見諒。