結對編程我一直認爲是一種很是好的合做方式,他的形式主要是由一我的負責代碼編寫,另外一我的則在一旁即時對寫下的代碼進行審查,這樣能夠大大減小代碼實現方面的錯誤。node
此次個人結對夥伴是小蘆薈(學號後四位爲1221)。他平時喜歡打籃球,打的也挺不錯的,三國殺也是高手(都100多級了),是一個比較靠譜的人。可是在編程這方面他可能不太擅長,所以此次結對項目就變成了我一我的寫,他在旁邊看着……不過有時他也會指出個人代碼中很是明顯的問題,這也保證了個人代碼正確性較高。設計的單元測試幾乎全是一次經過。算法
附結對編程圖片:express
本次結對項目要求對上次的我的項目進行封裝,並寫一個界面來調用這些封裝好的函數。這就須要咱們對相關接口制定一個規範,我和另外一個隊伍(pair16)的同窗約定好了代碼接口,便於以後的測試。編程
對於Information Hiding原則,咱們此次其實作的並很差,全部的類屬性也均爲public,這主要考慮到本次程序會封裝爲程序編寫的方便。數組
咱們core部分均採用Win32 Console Application實現,圖形界面部分均採用MFC Application實現。core編寫完成,測試完成後,生成dll並提供兩個接口,用來實現要求的兩個功能。接口的定義均提早約定。函數
關於接口定義、dll封裝的具體內容在第二篇博客中會詳細介紹。工具
算法設計單元測試
咱們本次項目沿用了上次個人我的項目的設計,只不過在其基礎上添加了對負數、有無括號、有無乘除法的限制,以及對運算符個數的限制。測試
具體來講,對於四則運算題目生成的部分:ui
其中,在生成表達式樹的過程當中,首先須要判斷樹中當前的節點是否爲分支節點(即運算符)。若是當前的樹的總結點數爲0,那麼該節點必須爲分支節點,若是當前樹中的分支節點已經打到了要求的上限,則該節點必須爲葉子結點(即操做數)。有了這個信息以後,針對當前結點的類型不一樣,就可生成對應的結構,以後若是當前結點爲分支節點的話,就遞歸生成其左右子樹。
在對錶達式進行正確性檢驗的過程當中,若是當前結點爲葉子節點,那麼咱們僅須要檢驗這個葉子結點的數值是否知足要求。不然,先遞歸對它的左右子樹進行正確性檢驗,在確保左右子樹正確的狀況下,檢驗當前結點的運算是否會形成不合法的狀況,若是有的話則進行修復。
在對錶達式最小表示的過程當中,一樣是先遞歸對其左右子樹進行最小表示,以後再看,若是當前結點爲'+'或'×',則判斷一下他的兩個子樹的hash值大小,在不改變運算順序的前提下使表達式變爲最小標識的形式。
檢驗算式仍然採用了第一次做業的形式,以一個STL的set來存放最小表示後的字符串,經過字符串的比較進行判重。
對於計算表達式結果的功能,仍然沒什麼好說的,採用了STL的兩個棧來維護。
具體實現
首先來看UML類圖:
本次項目中共用到了4個類。CFactor類是對上次Factor的一個擴展,加入了對負數的支持。CExpressionNode類是表達式樹的一個節點。CExpression類是表達式樹,CProblemSet類對兩種操做進行了封裝。這四個類造成如上的關聯關係。
根據這個這個類圖,順便說一下本次結對項目的代碼規範:
這樣的規範主要考慮到本次項目要與MFC結合,所以使用了一些Win32的代碼習慣。
CFactor類中,我重載了各類運算符,包括輸入輸出、四則運算和比較運算符。重載運算符後會大大下降編程複雜度,可是過多地採用流輸入輸出可能會對程序效率形成影響……這也是我在測試的時候才發現的問題。
CExpressionNode類則沒什麼好說的,就是儲存了一個樹節點的信息,包括其左右子樹、當前結點的運算符以及當前子樹的表達式的值。
CExpression類則是一個表達式樹,他內部採用了一個CExpressionNode類型的數組用來存儲表達式中的全部結點,並經過new_node
方法實現獲取一個新節點的操做。這樣作避免了每次的動態內存分配,必定程度上能夠提升程序效率,可是這樣作則要求表達式不能太長,不過在實際應用中不會用到太長的表達式。
CProblemSet類則沒什麼好說的了,他實例化了一個CExpression類的對象,每次調用該類的 build_expression_tree
方法生成一個表達式並使用set進行重複檢驗。
本次項目的基礎就是CFactor類,若是該類的實現有問題,那麼全部功能都不能正常工做,所以我主要對該類進行了單元測試。
VS2013單元測試我也是第一次使用,不知道爲何Managed Test Project 建立後會沒法鏈接C++console Application的代碼,最後採用了 Native Unit Test Project 來作單元測試,它的語法與Managed Test Project略有不一樣,可是也很簡單,我針對CFactor類的各類方法寫了37條Unit Test, 而且所有經過了。
代碼覆蓋率:
注:個人VS2013是社區版,沒有代碼覆蓋率分析工具,因此在我編寫完測試用例後,借用了同寢室的另外一我的的電腦來測試並進行代碼覆蓋率檢驗。