小学生四则运算练习软件项目报告
github地址:https://github.com/Opalus-wangs/ws-lib/tree/master
一、需求分析
- 由用户输入参数n。
- 系统随机生成随机产生
- 每个数字在 0 和
- 每个练习题至少要包含2种运算符。且所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3/5+2=2.6,2-5+10=7等算式。
- 练习题生成好后,学号
- 当程序接收的参数为4时,以下为输出文件示例。
二、功能设计
- 实现生成n个可以加减乘除四则运算的式子并能输出正确结果
- 式子中的每一个值都在0~100之间
- 每个式子都含有有3-5个运算数
- 式子的结果不为负,且除法不会出现非整数
- 支持有括号的运算式
三、功能实现
- 程序模块及功能
- 程序流程图
四、运行测试
- Eclipse窗口运行结果:
- cmd窗口运行结果:
五、核心代码
- 生成运算式(以四个操作数为例)
1 case 4: 2 int a1 = (int)(Math.random()*100)+1; 3 int b1 = (int)(Math.random()*100)+1; 4 int c1 = (int)(Math.random()*100)+1; 5 int d1 = (int)(Math.random()*100)+1; 6 int x1 = (int)(Math.random()*symbol.length); 7 int y1 = (int)(Math.random()*symbol.length); 8 int z1 = (int)(Math.random()*symbol.length); 9 int bracket1 = (int)(Math.random()*4);//括号,注意四个式子中括号为2个,此时有3种情况 10 if(bracket1==0)//0表示没有括号 11 { 12 len=String.valueOf(a1)+String.valueOf(symbol[x1])+String.valueOf(b1)+String.valueOf(symbol[y1]
+String.valueOf(c1)+String.valueOf(symbol[z1])+String.valueOf(d1)+"= "); 13 } 14 else if(bracket1==1) 15 { 16 len="("+String.valueOf(a1)+String.valueOf(symbol[x1])+String.valueOf(b1)+")"+String.valueOf(symbol[y1]
+"("+String.valueOf(c1)+String.valueOf(symbol[z1])+String.valueOf(d1)+")"+"= "); 17 } 18 else if(bracket1==2) 19 { 20 len="("+"("+String.valueOf(a1)+String.valueOf(symbol[x1])+String.valueOf(b1)+")"+String.valueOf(symbol[y1]
+String.valueOf(c1)+")"+String.valueOf(symbol[z1])+String.valueOf(d1)+"= "); 21 } 22 else 23 { 24 len=String.valueOf(a1)+String.valueOf(symbol[x1])+"("+String.valueOf(b1)+String.valueOf(symbol[y1]
+"("+String.valueOf(c1)+String.valueOf(symbol[z1])+String.valueOf(d1)+")"+")"+"= "); 25 } 26 operation cal1 = new operation(); 27 long result1=cal1.caculate(len); 28 if(result1!=999999) 29 { 30 System.out.println(len+result1); 31 pw.println(len+result1); 32 } 33 34 else 35 i--; 36 break;
- 运算过程
1 while (!comparePri(ch) && !symbolStack.empty()) { 2 long b = numberStack.pop(); 3 long a = numberStack.pop(); 4 long midtemp=0; 5 switch ((char) symbolStack.pop()) { 6 case '+': 7 numberStack.push(a + b); 8 break; 9 case '-': 10 midtemp = a - b; 11 if(midtemp<0) { //判断减法结果是否为负数 12 midtemp=0; 13 exp = false; 14 } 15 numberStack.push(midtemp); 16 break; 17 case '*': 18 numberStack.push(a * b); 19 break; 20 case '/': //判断除法是否合法,且能整除 21 if(b==0) { 22 b=1; 23 exp = false; 24 } 25 midtemp = a / b; 26 if(midtemp*b!=a) 27 exp = false; 28 numberStack.push(midtemp); 29 break; 30 default: 31 break; 32 } 33 } 34 if (ch != '=') { 35 symbolStack.push(new Character(ch)); // 符号入栈 36 if (ch == ')') { // 去右括号 37 symbolStack.pop(); 38 symbolStack.pop(); 39 } 40 } 41 } 42 } 43 // 返回计算结果 44 if(exp) 45 return numberStack.pop(); 46 else 47 return 999999;
六、总结
第一次看到这个题目的时候给我的感觉是之前做过类似的程序,所以应该不是很困难,但是当我认真分析了题目之后,我发现这个题目和我之前做过的内容都不太一样,要实现所有的功能还是有一定难度的,而且在做的过程中我由于提前没有先好好的分析题目,匆忙动手,有很多细节的问题都没有考虑清楚,在做的过程中就需要大量的返工,而且我第一次尝试写的时候是先做的三位数的运算,当我代码长度写到200多行的时候将三位数运算解决之后,我发现了一个致命的问题,就是这个运算附的优先级和扩展性问题,如果还是按照之前的写法的话,每多一个运算数,代码的长度是指数倍的增长且不具备扩展性,于是我又重新分析了题目,推翻了之前的写法,采取了逆波兰后缀表达式的方法来解决运算式优先级问题,我就发现在一个项目中前期的设计分析是非常重要的,只有做好基础的工作才能在后面的实现中进展顺利,但是我最后的项目在生成运算式的程序中还是有许多的冗余代码,代码不够精炼,也没有实现真分数的运算,在后面我也会对此次项目代码进行完善和补充,希望越来越进步。
七、生成PSP
PSP2.1 | 任务内容 | 计划完成的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
PLanning | 计划 | 20 | 25 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 20 | 25 |
Developmet | 开发 | 240 | 510 |
Analysis | 需求分析(包括学习新技术) | 20 | 20 |
Design Spec | 生成设计文档 | 10 | 5 |
Design Revie | 设计复审(和同事审核设计文档) | 10 | 5 |
Coding Standard | 代码规范 | 5 | 10 |
Design | 具体设计 | 30 | 40 |
Coding | 具体编码 | 140 | 400 |
Code Review | 代码复审 | 10 | 5 |
Test | 测试(自我测试,修改代码,提交修改) | 15 | 25 |
Reporting | 报告 | 30 | 55 |
Test Report | 测试报告 | 20 | 35 |
Size Measurement | 计算工作量 | 5 | 5 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改机计划 | 5 | 15 |