1. 程式人生 > >結對項目:最長單詞鏈

結對項目:最長單詞鏈

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.結對編程及其優缺點:

結對編程:

  • 優點:兩人結對配合,能力有所互補,互相督促和幫助。
    便於討論問題,能在編程的同時交流想法,快速解決問題。
  • 缺點:個人習慣不同,時間也難以統一,有時會帶來一些麻煩。

    個人優缺點:

  • 優點:抗壓能力較強,學習積極性較高,熱心學習對方的長處。
  • 缺點:個人能力薄弱。

    結對同學優缺點:

  • 優點:個人能力強,執行力強,項目進展推進快。
  • 缺點:比較專心,交流較少。

結對項目:最長單詞鏈