git http地址: https://git.coding.net/clairewyd/f4.git git
SSH地址:git@git.coding.net:clairewyd/f4.git編程
要求1 參考《構建之法》第4章兩人合做,結對編程上述功能,要求每人發佈隨筆1篇 (代碼是共同完成的,博客是分別完成的)。 (1) 給出每一個功能的重點、難點、編程收穫。(2)給出結對編程的體會,以及 (3) 至少5項在編碼、爭論、複審等活動中花費時間較長,給你較大收穫的事件。 (10分)數組
功能1 的主要實現過程:函數
定義Question類實現功能1 的主要功能,該類中定義numStack,和operatorStack兩個Stack類型的類成員變量分別用來存放產生的隨機數學運算式的數字,運算符及最後產生的運算式結果。首先產生數學表達式,在TheFinal方法中進行調用GetStack方法運算並判斷它是不是符合條件的運算式,若是是則輸出在控制檯,以後進行下一步操做,不然從新生成表達式。工具
主要函數:單元測試
用於計算數學表達式結果GetStack(char[] stackArr)。形參是一個字符數組,若是是數字則加入數字棧,若是是「+」或者「-」則判斷符號棧棧頂元素,若是棧頂元素是四則運算符號則進行退棧計算操做,將中間結果加入數字棧,不然直接將符號加入符號棧。若是是「*」,「/」則判斷符號棧棧頂元素,若是爲「*」或者「/」,則進行退棧計算。遍歷完以後,若是此時符號棧不爲空,則繼續調用退棧函數進行計算,最後數字棧棧頂元素即爲表達式的結果。測試
/// <summary> /// 進行堆棧操做,最後numstack的棧頂元素爲結果 /// </summary> /// <param name="stackArr"></param> public void GetStack(char[] stackArr) { for (int i = 0; i < stackArr.Length; i++) { if (stackArr[i] - '0' >= 0 && stackArr[i] - '0' <= 9) { double num = double.Parse(stackArr[i].ToString()); NumStack.Push(num); } else { if (OperatorStack.Count == 0) { OperatorStack.Push(stackArr[i]); } else { if (stackArr[i] == '+' || stackArr[i] == '-') { char oper = (char)OperatorStack.Peek(); if (oper == '+' || oper == '-' || oper == '*' || oper == '/') { //退棧函數,計算中間結果並將相應數字棧和符號棧進行退棧操做 TempResult(NumStack, OperatorStack); OperatorStack.Push(stackArr[i]); } else { OperatorStack.Push(stackArr[i]); } } else if (stackArr[i] == '*' || stackArr[i] == '/') { char oper = (char)OperatorStack.Peek(); if (oper == '*' || oper == '/') { TempResult(NumStack, OperatorStack); OperatorStack.Push(stackArr[i]); } else { OperatorStack.Push(stackArr[i]); } } } } } while (OperatorStack.Count != 0) { TempResult(NumStack, OperatorStack); } }
功能2:ui
功能2部分代碼在QuestionBracket類中實現,該類直接繼承自功能1部分的Question類,重載了GetStack方法,加入計算括號的功能。當操做符是」(「時直接加入符號棧,當是」)「時則調用TempResul函數直至")"出棧爲止。this
/// <summary> /// 進行堆棧操做,最後numstack的棧頂元素爲結果 /// </summary> /// <param name="stackArr">參加運算的字符數組</param> new public void GetStack(char[] stackArr) { for (int i = 0; i < stackArr.Length; i++) { if (stackArr[i] - '0' >= 0 && stackArr[i] - '0' <= 9) { double num = double.Parse(stackArr[i].ToString()); NumStack.Push(num); } else { if (OperatorStack.Count == 0 || stackArr[i] == '(') { OperatorStack.Push(stackArr[i]); } else { if (stackArr[i] == '+' || stackArr[i] == '-') { char oper = (char)OperatorStack.Peek(); if (oper == '+' || oper == '-' || oper == '*' || oper == '/') { TempResult(NumStack, OperatorStack); OperatorStack.Push(stackArr[i]); } else { OperatorStack.Push(stackArr[i]); } } else if (stackArr[i] == '*' || stackArr[i] == '/') { char oper = (char)OperatorStack.Peek(); if (oper == '*' || oper == '/') { base.TempResult(NumStack, OperatorStack); OperatorStack.Push(stackArr[i]); } else { OperatorStack.Push(stackArr[i]); } } else if (stackArr[i] == ')') { while (((char)base.OperatorStack.Peek()) != '(') { TempResult(base.NumStack, base.OperatorStack); } base.OperatorStack.Pop(); } } } } while (OperatorStack.Count != 0) { TempResult(NumStack, OperatorStack); } }
功能3 :功能3和功能2 均在QuestionBracket類中,該功能主要使用了字符串的格式化,及文件的寫入。編碼
/// <summary> /// 功能3寫入文件 /// </summary> public void SaveFile() { string path = "question.txt"; StreamWriter streamWriter = new StreamWriter(path, true); string question = this.TheFinal(); //進行格式化寫入 streamWriter.Write(string.Format("{0,-50}", question)); //獲取計算結果並寫入 streamWriter.Write((double)base.NumStack.Peek()); streamWriter.WriteLine(); Console.WriteLine(string.Format("{0,-50}", question) + (double)base.NumStack.Peek()); streamWriter.Flush(); streamWriter.Close(); }
功能4實如今參考了資料後只能實現兩個分數的加減乘除,結果約分後以帶分數的形式輸出,可是由於前幾部分的堆棧存儲結構問題使實現完整功能四要求有困難。
如下是實現分數約分,拼接功能的函數:
private static string Convert(int fz, int fm) { if (fz == 0) return "0"; if (fm == 0) { return "Inf"; } StringBuilder result = new StringBuilder(); Boolean flag = false; int k = 0; if (fz < 0) { result.Append("(-"); fz = -fz; flag = true; } k = fz / fm; fz = fz % fm; if (fz == 0) { if (k != 0) result.Append(k); if (!flag) return result.ToString(); else return result.Append(")").ToString(); } int gcd = Gcd(fz, fm); if (gcd != 1) { fz /= gcd; fm /= gcd; } if (k != 0) result.Append(k).Append(" "); result.Append(fz).Append("/").Append(fm); if (flag) result.Append(")"); return result.ToString(); }
功能4 完成部分
1 在代碼規範編寫過程當中,因爲兩人的編碼風格不一樣,產生過度歧。代碼規則中有一條單行註釋放在代碼行上方,可是兩人中有一人習慣放在右側,因此討論了好久。
2 對於代碼的邏輯結構也產生過度歧,當時討論了兩種實現方法,一種是使用接口,讓各個功能的工具類均實現這一接口,一種是如今程序所採用的以功能一實現類Question爲父類,其餘功能繼承Question類。採用這一結構是由於這樣實現更有邏輯性,並且只需重寫一部分函數,代碼可讀性更好,更加簡潔。
3 代碼複審時因爲代碼規範不夠嚴謹(關鍵語句須要加註釋),因爲對「關鍵」一詞有分歧,因此找了室友王靜茹進行代碼閱讀,除本來有註釋的代碼行,對於她有疑問的代碼就加入代碼註釋。
4 編碼時用於產生最後輸出運算式的theFinal方法,在產生的運算式不符合要求要產生新的運算式時,因爲忘記清空Numstack棧,會產生異常,排查了好久,才找到緣由。
5 單元測試中GetStack函數中有不少分支結構,爲了可以完成全部的條件覆蓋,因此設計測試用例花費了一些時間。
要求2 給出照片1張,包括結對的2位同窗、工做地點、計算機,可選項包括其餘能表達結對編程工做經歷的物品或場景。 (5分)