软件工程——第四次作业(3)
软件工程——第四次作业(3)
四则运算试题生成
作业要求:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/997
代码:https://git.coding.net/ss505072461/f4.git
————————————————————————————————————————————
本次作业的要求,是编写出一款能够生成四则运算试题的程序,在阅读了老师发布的作业要求之后,我便开始了对于程序功能要求的分析及实现目标功能的个人想法。
功能1是该程序的基本需求,即四则运算题目的生成及计算,程序要求支持出题4个数的四则运算题目,题目总数在样例中是20道,所有题目要求作者有能力正确回答,因此如果结果是无限的小数,是没有办法回答的(没有办法输入完整结果)。
作为一个自动出题的程序,题目的4个数都是随机生成的整数,而题目中的3个四则运算符也是随机生成的,因此题目的运算顺序会因为随机生成的乘和除运算而发生变化,我的初步想法是题目里的4个数暂定范围为[1,99]的整形数,这样结果也能在一定考虑范围内。关于四则运算符的生成,我选择随机生成一个[0,3]的整形数,分别对应+、-、*、/四个运算符,三个运算符的生成数由整形一维数组symbol保存,而后生成的三个用于输出题目的运算符则是由字符型一维数组sym保存。
程序的主函数main如下(其中包含了功能3中对于命令行参数及题目数量是否为正整数的判断内容):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 static void Main(string[] args) 2 { 3 int num = 20; //在是否有命令行参数判断之前,默认题目为20道 4 if (args.Length > 0 && args[0] == "-c") 5 if (IsNumeric(args[1]) == false) //功能3中,命令行-c参数后内容是否为正整数的检测 6 { 7 Console.WriteLine("题目数量必须是 正整数"); 8 System.Environment.Exit(0); 9 } 10 else 11 { 12 num = int.Parse(args[1]); 13 } 14 for (int i = 0; i < num; i++) 15 { 16 Create(); 17 } 18 Console.WriteLine(); 19 Console.WriteLine("你一共答对{0}道题,共{1}道题。", right, num); 20 }
其中生成题目用函数Create的部分内容:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void Create() 2 { 3 string astring, bstring, cstring, dstring; 4 float answer; 5 int a,b,c,d; 6 int[] symbol = new int[3]; 7 char[] sym = new char[] { '+', '-', '*', '/' }; 8 for (int i = 0;i < 3;i++) 9 { 10 symbol[i] = ran.Next(0, 4); 11 switch(symbol[i]) 12 { 13 case 0: 14 sym[i] = '+'; 15 break; 16 case 1: 17 sym[i] = '-'; 18 break; 19 case 2: 20 sym[i] = '*'; 21 break; 22 case 3: 23 sym[i] = '/'; 24 break; 25 } 26 } 27 a = ran.Next(1, 10); 28 b = ran.Next(1, 10); 29 c = ran.Next(1, 10); 30 d = ran.Next(1, 10); 31 astring = a.ToString(); 32 bstring = b.ToString(); 33 cstring = c.ToString(); 34 dstring = d.ToString(); 35 Console.Write(astring + sym[0] + bstring + sym[1] + cstring + sym[2] + dstring + "= "); 36 string input = Console.ReadLine(); 37 answer = float.Parse(input); 38 float res = Result((float)a, (float)b, (float)c, (float)d, symbol[0], symbol[1], symbol[2]); 39 if (answer == res) 40 { 41 Console.WriteLine("答对啦,你真是个天才!"); 42 right++; 43 } 44 else 45 { 46 Console.WriteLine("再想想吧,答案似乎是{0}喔!", res); 47 wrong++; 48 } 49 return; 50 }
在实现功能1的过程中,题目的结果计算是重中之重,毕竟如果一个出题程序自己都不知道题目结果那就太失败了……我碰到的问题是由于运算乘和除的优先级要高于加和减,并且运算符是随机生成的,因此题目的计算是需要进行优先级的处理,我参考了网上的一些内容,看到一些想法是将括号/乘除/加减进行三个层次的优先级规划,然后再利用栈的方式进行题目的计算。
功能实现的截图:
功能2的要求是支持括号,那么对于题目计算,优先级要加入比乘除更高的括号,而括号的生成,曾经的想法是先随机生成左括号的位置,再随机生成括号的长度(包含几个数字),但是由于我们水平不够,并没有实现(题目生成后却不会算出结果……)。
功能3的要求是开始支持命令行参数输入及题目数量的输入,随后可以“精美”打印输出。对于命令行参数的输入和题目数量的变更输入,我在主程序中加入了实现的代码,并实现了题目数量输入内容的正整数判断。而后续的打印输出则没有实现。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static bool IsNumeric(string str) //正整数检测 { System.Text.RegularExpressions.Regex reg1 = new System.Text.RegularExpressions.Regex(@"^[0-9]\d*$"); return reg1.IsMatch(str); }
题目数量实现:
这一次的作业要求是结对编程,我在阅读了《构建之法》后,对于这种编程方式也充满了兴趣,因此在发布了作业要求后,我选择了室友葛美义作为结对编程的队友,选择的编程地点是寝室,其优势是工作环境熟悉,交流也快捷方便。在这次结对编程的过程中,我也感受到了结对编程的规范性,两人共同制定相应的规则,相互交流,对于成果也是荣辱与共。
在结对编程的过程中,由于在结对编程方面,我们也是初次涉及,首先碰到的第一个问题就是谁来编写代码,葛美义擅长的是C++和java,而我是在C#的学习过程中,也是想有更多的实践机会。最终,是葛美义选择领航,而我来编写代码;第二个问题是关于规则的制定,由于两人在过去学习环境的不同,甚至编程语言的不同,对于编程的习惯和个人规范也是大不相同,因此要制定出一个合理的规则以及去严格执行也是一个难点;三是在我们两人在交流实现目标功能的过程中,对于各种功能,其实都是各自有着一定的实现方法,而在我开始编码后,却因为我个人的编码水平问题,导致有很多功能的实现想法并没有实现;四是在这几天的结对编程中,每天的几个小时工作时间上的安排也是一个问题,在一个寝室的优势是交流简便,但是各自都有着各自的私人时间,甚至由于中间的8天长假,俩人的精神状态和一些想法都有着一定的变动;最后,在测试的过程中,对于测试的深度两人也有着一些争论。
结对编程的环境:
在宿舍,邵朔和葛美义,外接显示器和笔记本,两个人不用挤在一起看屏幕了……