github项目地址 : FourFundamentalOperations
实验要求
- 为了让小学生得到充分锻炼,每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3/5+2=2.6,2-5+10=7等算式。
- 练习题生成好后,将你的学号
- 当程序接收的参数为4时,以下为输出文件示例。
- 代码结构
4、运行测试
- 测试输入错误字符:
- 测试不输入生成算式的数量,默认为5,可正常运行
- 测试生成算式
5、核心代码
- 随机生成逆波兰式
1 ArrayList<String> strArr=new ArrayList<String>(); 2 List list = Collections.synchronizedList(strArr); 3 N = new Random().nextInt(4)+2; 4 synchronized(list) { 5 strArr.clear(); 6 for (int i = 0; i < N; i++) { 7 strArr.add(ele.random_N()); 8 } 9 for (int i = 0; i < N - 2; i++) { 10 strArr.add(new Random().nextInt(strArr.size() - N + 1) + N - 1, ele.random_E()); 11 } 12 strArr.add(strArr.size(), ele.random_E()); 13 } 14 ele.setStrArr(strArr);
- 通过逆波兰式生成运算式
1 private static void pro_exp(ArrayList<String> strArr){ 2 String str = ele.getOperations(); 3 String ea,eb; 4 Stack<String> expstack = new Stack<String>(); 5 for(String s : strArr){ 6 if(!str.contains(s)){//如果是数字,放入栈中 7 expstack.push(s); 8 }else{ 9 ea = expstack.pop(); 10 eb = expstack.pop(); 11 switch(s){ 12 case "+" : 13 expstack.push( "("+eb+"+"+ea+")"); 14 break; 15 case "-" : 16 expstack.push("("+eb+"-"+ea+")"); 17 break ; 18 case "*" : 19 expstack.push( eb+"*"+ea); 20 break; 21 case "/" : 22 expstack.push( eb+"/"+ea); 23 break ; 24 } 25 } 26 } 27 ele.setExp(expstack.pop()); 28 }
- 通过逆波兰式计算结果
1 private static boolean evoe(ArrayList<String> strArr){ 2 String str = ele.getOperations(); 3 boolean flag = true;//判断过程中是否有负数或小数点 4 int temp=0;//存放临时计算结果 5 Stack<String> stack = new Stack<String>(); 6 for(String s : strArr){ 7 if(!str.contains(s)){//如果是数字,放入栈中 8 stack.push(s); 9 }else{ 10 int a = Integer.valueOf(stack.pop()); 11 int b = Integer.valueOf(stack.pop()); 12 try { 13 switch(s){ 14 case "+" : 15 stack.push(String.valueOf(a+b)); 16 break; 17 case "-" : 18 temp = b-a; 19 if(temp<0) flag=false; 20 stack.push(String.valueOf(temp)); 21 break ; 22 case "*" : 23 stack.push(String.valueOf(a*b)); 24 break; 25 case "/" : 26 if(a==0) {a=1;flag=false;} 27 temp = b/a; 28 if(a*temp != b) flag=false; 29 stack.push(String.valueOf(temp)); 30 break ; 31 } 32 } catch (Exception e) { } 33 } 34 } 35 ele.setResult(Integer.parseInt(stack.pop())); 36 return flag; 37 }
6、总结
使程序模块化,即主要以面向对象的方法,我主要分为元素层和操作层,元素层为所有的操作符及数字,操作层为生成运算式和计算结果的这些方法。
7、展示PSP
PSP2.1 |
任务内容 |
计划完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
30 |
30 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
30 |
30 |
Development |
开发 |
230 |
255 |
Analysis |
需求分析 (包括学习新技术) |
30 |
30 |
Design Spec |
生成设计文档 |
10 |
10 |
Design Review |
设计复审 (和同事审核设计文档) |
10 |
10 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
5 |
5 |
Design |
具体设计 |
30 |
30 |
Coding |
具体编码 |
120 |
130 |
Code Review |
代码复审 |
10 |
10 |
est |
测试(自我测试,修改代码,提交修改) |
15 |
30 |
Reporting |
报告 |
30 |
43 |
Test Report |
测试报告 |
25 |
30 |
Size Measurement |
计算工作量 |
2 |
3 |
Postmortem & Process Improvement Plan |
事后总结 ,并提出过程改进计划 |
3 |
10 |
项目总结
此次项目看似难度不大,但要追求完美,需要多很多工作。最开始为了简化代码,并没有选择一般性的方法,即先生成运算式,再计算结果,而是选择直接随机生成逆波兰式,再将其转化为运算式并计算结果,本是为了简化和节约时间,但实际却花费了更多的时间,就从逆波兰式转化为带有括号的运算式,使我困惑了好久,但最终的收获也不少,让我对逆波兰式以及栈的操作有了很深的认识。就这样看似不大的项目,却有不少的干货,希望以后的实践中可以有更多的收获以及更大的进步。