結對項目:最長單詞鏈
阿新 • • 發佈:2019-03-15
can 有時 步驟 class 遍歷 reporting 抽象 之間 修改
1.Github項目地址:
Wordlist
2.PSP表格及預估開發時間:
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 30 | 20 |
· Estimate | · 估計這個任務需要多少時間 | 10 | 10 |
Development | 開發 | 1400 | 1700 |
· Analysis | · 需求分析 | 240 | 300 |
· Design Spec | · 生成設計文檔 | 20 | 0 |
· Design Review | · 設計復審(和同事審核設計文檔) | 30 | 0 |
· Coding Standard | · 代碼規範(為目前的開發制定合適的規範) | 30 | 30 |
· Design | · 具體設計 | 120 | 180 |
· Coding | · 具體編碼 | 600 | 720 |
· Code Review | · 代碼復審 | 60 | 50 |
· Test | · 測試(自我測試,修改代碼,提交修改) | 300 | 420 |
Reporting | 報告 | 120 | 180 |
· Test Report | · 測試報告 | 50 | 30 |
· Size Measurement | · 計算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事後總結,並提出過程改進計劃 | 120 | 120 |
Total | 合計 | 1740 | 2070 |
3.教程與設計:
- Information Hiding,即信息隱藏,類似於大二面向對象編程中的代碼封裝。和授課老師常說的 “你要什麽告訴我,我拿給你” ,區別於將口袋裏的東西直接展示給使用者,封裝後的代碼隱藏實現需求的具體步驟,留下接口給使用者調用,或者類的方法的調用。在本次作業中,我們將計算部分的核心代碼封裝為一個Core類,並分離出來,為它配置了數個接口,讓外界調用來獲得期望的數據,但不對外暴露實現的具體方法,隱藏了代碼的運行過程和信息。
- Interface Design,即接口設計,既是一種好的習慣也是一個非常重要的手段。通過將一個類集合成一個或幾個特定的接口,使用戶對於程序的使用通過接口來進行,符合面型對象的思想,同時也便於維護和擴展。本次作業裏要求的兩個接口nt gen_chain_word(char* words[], int len, char* result[], char head, char tail, bool enable_loop)和int gen_chain_char(char* words[], int len, char* result[], char head, char tail, bool enable_loop)就很直觀的體現了單詞鏈程序本身的特點,也便於測試。
- Loose Coupling,即松耦合,是指程序的不同功能之間耦合度較低,不互相依賴,任何一個功能的使用和修改對其他的功能影響不大。在本次作業中,要求將核心計算過程封裝為Core單獨分離出來,並產生dll文件,可以通過命令行來進行測試和調用。
4.計算模塊接口的設計與實現過程:
- 深度優先算法(DFS)和拓撲排序、動態規劃。將有長度的單詞看做帶權的有向邊,通過將入度為零的節點(單詞的首位字母)不斷去掉,減少26*26的有向圖中的點,得到一個拓撲序列,再按照得到的序列向最後一個(被指向最多的尾字母)延伸,記錄途中的信息,就能得到“最長路徑”(“-c”)。其他要求基本可以從該方法演變(“-w”可視為“-c”中邊長度全為一,“-h”,“-t”即對最長路徑的截取)而來。
5.UML:
6.計算模塊接口部分的性能改進:
- 一開始獨立設計時采用了DFS,用近乎暴力枚舉的方式寫了一個最長路徑的算法,結果在跑測試數據時久久不能輸出結果,思考後發現性能基本消耗在遞歸的過程中。於是采用了拓撲排序的方法,避免遞歸,並在盡量少的遍歷次數下完成排序和路徑的生成。再完成後面對一萬左右的單詞量就可以用幾秒算出結果了。
7.Design by Contract:
- 契約式設計(編程)要求軟件設計者為軟件組件定義正式的,精確的並且可驗證的接口,這樣,為傳統的抽象數據類型又增加了先驗條件、後驗條件和不變式。
- 契約式設計規定了一個程序模塊確定的接口,讓程序設計更精確,在多人共同開發時不會互相影響產生混亂。在結對編程中保證了設計接口時具備先驗條件、後驗條件和不變條件,能互相配合。
8.計算模塊部分異常處理說明:
void judge() {
if (wflag == 1 && cflag != 1 && rflag != 1) {
wchain();
}
else if (wflag != 1 && cflag == 1 && rflag != 1) {
cchain();
}
else if (wflag == 1 && cflag == 1 && rflag != 1) {
cout << "ERROR, -w and -c can not be both requested!" << endl;
}
else if (rflag == 1) {
rchain();
}
}
- 不允許-w和-c兩種方法同時使用。
if ((fopen_s(&fp, cpath, "r")) != 0) {
printf("file not exist\n");
}
- 對錯誤路徑異常的輸出。
9.界面模塊與計算模塊的對接:
for (int ar = 1; ar < argv; ar++) {
if (argc[ar][0] == '-') {
if (argc[ar][1] == 'w') {
wflag = 1;
if (argc[ar + 1][0] != '-') {
strcpy_s(cpath, argc[ar + 1]);
}
}
else if (argc[ar][1] == 'c') {
cflag = 1;
if (argc[ar + 1][0] != '-') {
strcpy_s(cpath, argc[ar + 1]);
}
}
else if (argc[ar][1] == 'r') {
rflag = 1;
}
else if (argc[ar][1] == 't') {
tflag = 1;
top = argc[ar + 1][0];
}
else if (argc[ar][1] == 'h') {
hflag = 1;
hop = argc[ar + 1][0];
}
}
}
在讀入參數之後,進行命令行參數的處理,判斷參數的正確性,並根據參數來分別調用Core模塊中的接口進行計算。
10.結對過程:
11.結對編程及其優缺點:
結對編程:
- 優點:兩人結對配合,能力有所互補,互相督促和幫助。
便於討論問題,能在編程的同時交流想法,快速解決問題。 缺點:個人習慣不同,時間也難以統一,有時會帶來一些麻煩。
個人優缺點:
- 優點:抗壓能力較強,學習積極性較高,熱心學習對方的長處。
缺點:個人能力薄弱。
結對同學優缺點:
- 優點:個人能力強,執行力強,項目進展推進快。
缺點:比較專心,交流較少。
結對項目:最長單詞鏈