我的工程總結

PSP2.1算法

Personal Software Process Stages模塊化

Time 性能

Planning學習

計劃測試

 

  · Estimate大數據

  · 估計這個任務須要多少時間優化

 8編碼

Developmentspa

開發設計

 

  · Analysis

  · 需求分析 (包括學習新技術)

 0.5

  · Design Spec

  · 生成設計文檔

 0.5

  · Design Review

  · 設計複審 (和同事審覈設計文檔)

 0

  · Coding Standard

  · 代碼規範 (爲目前的開發制定合適的規範)

 0

  · Design

  · 具體設計

 2

  · Coding

  · 具體編碼

 4

  · Code Review

  · 代碼複審

 0.5

  · Test

  · 測試(自我測試,修改代碼,提交修改)

 2

Reporting

報告

 

  · Test Report

  · 測試報告

 0.5

  · Size Measurement

  · 計算工做量

 0.5

  · Postmortem & Process Improvement Plan

  · 過後總結, 並提出過程改進計劃

 1.5

 

合計

 12

 

0x01 設計

用一句話歸納本次的需求,給小學生出算術題。考慮小學生的算術題,不難發現,其中所出現的數字僅僅包含整數和分數,且全部分數使用真分數的形式表示。每一個算式由這些數字和運算符組成,其中運算符包括加、減、乘、除、小括號。不難發現,輸出中的乘除號均爲Unicode字符而非ASCII字符,因此本次使用C#語言來回避編碼問題。(用C++的不要打我…)

根據這樣的需求,能夠選擇構造一個層次結構:算式由數字組成。所以,首先須要實現的就是數字類和算式類。只要讓這兩個類具備隨機生成的功能,本次需求便很容易實現。

對於數字類,咱們知道整數能夠表示成特殊的分數,即分母是1的分數。那麼咱們就能夠用統一的形式來表示全部數字。

Class 數字 = {分子, 分母}。

那麼輸出怎麼辦?對於數字的輸出,咱們只須要重載一下ToString()方法即可以解決多種輸出格式。在ToString()方法中,判斷數字是整數、帶有整數部分的真分數仍是不帶有整數部分的分數,選擇相應的格式輸出便可。

隨後,重載數字類的加減乘除和比較運算,便可在代碼中直接使用這些運算符。

有了數字,咱們如今就要插入運算符,使之構成算式了。咱們在學習中綴表達式計算的時候提到過,可使用棧來記錄運算過程。程序實現借鑑這個思想,構造數字棧和符號棧來模擬後綴表達式的運算,拼接成算式。爲了更加有效的判重,我還引入一個數字變量來保存結果。

Class 算式 = {數字棧, 符號棧, 運算結果},

須要注意的一點是,與後綴表達式不一樣,使用兩個棧來保存算式,運算符和數字的關係是不肯定的,這時就須要咱們人爲地規定符號與數字的順序關係才能保證能夠計算出全部狀況。對於輸出,依然是重載ToString()方法,對兩個棧進行拼接。

斷定兩個算式是否相等,其實就是斷定每一步的運算是否相等。所以,兩個算式相等的充分必要條件是,符號棧徹底相等,且每次運算中的兩個運算數分別相等。也就是說,在斷定相等時,須要還原兩個表達式求值的全過程進行比較才行。這樣顯然是很慢的,後面會講到一個很是有效的優化。

 

0x02 測試

本次程序模塊清晰很是適合於進行模塊化測試。本次程序中,對於每個模塊方法都有單元模塊測試,能夠確保在不觸發異常的狀況下能夠返回正確的結果。(因爲時間有限,一場處理部分沒有進行測試。)對於程序全局功能的測試,採用極端數據和大數據量的方法,都獲得了正確的返回結果。

 

0x03 優化

判重:前面說到,判重的過程是很是慢的,由於要徹底還原每一步的運算狀態。那麼能不能找到一個有效的方式來大機率加速斷定呢?答案是確定的。對於每一個算式,咱們進行一次計算,保存下來計算的結果。對於任意兩個結果不一樣的算式,顯然是不能通過有限次交換同樣的。事實證實,這樣的優化能夠加快80%左右的斷定時間。以單次判斷爲基本單位,程序的時間複雜度爲O(n^2),所以即便優化之後,判斷依然是耗費時間最多的執行單元。

輸出:本次程序的輸出爲文本文件,每次輸出一個算式和一個結果。因爲兩步輸出是連續操做,若是每次直接輸出到文件,會因爲硬盤響應速度較慢形成阻塞。所以能夠選用Buffer做爲輸出緩衝,提升性能。這種方式在輸出量較小的狀況下(如連續執行100000次,每次輸出20個算式)對性能有明顯改進。

計算結果:本次需求中要求,全部算式在運算過程當中不能出現負數,所以在斷定過程當中就順帶完成告終果的計算。這樣能夠省去寫求結果的方法,直接服用check便可。

 

0x04 測試

正常數據測試:

         -r 10 –n 10000

         -r 3   -n 100

極端數據:

         -r 1   -n 100

         -r 2   -n 10000000000

         -r 1000000        -n 100

 

0x05 總結

本次工程難度不大,但需求數量較多。在實現需求以前,須要統一的設計來知足不一樣需求的實現。設計在本次工程中起到了很是大的做用。除此之外,本次工程還充分體現出了有一個屬於本身的類庫的重要性。

 

補充:性能分析圖以下,即使是優化後的算法,大量的時間依然花費在算式判重的問題上。這裏能夠考慮對每一個表達式進行最小轉換後進行Hash,使用Set來進行優化。

相關文章
相關標籤/搜索