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分)