2019-2020-4 《Java 程序设计》结对项目阶段总结---《四则运算——整数》
1、需求分析
实现一个命令行程序java
要求:git
- 自动生成小学四则运算题目(加,减,乘,除);
- 支持整数;
- 支持多运算符(例如生成包含n个运算符的题目);
- 支持真分数(后续实现);
- 统计正确率。
扩展需求编程
- 文件: (1) 处理生成题目并输出到文件; (2) 完成题目后从文件读入并判断。
- 多语言支持:简体中文,繁體中文,English;
- 生成题目去重。
2、设计思路以及代码解释
刚拿到结对项目数组
刚拿到结对项目时,感受不是很难,是由于没有考虑到括号、运算优先级以及多个数字运算的问题,因此只是简单设计了一个两个数字简单的四则运算,具体程序以下:dom
//生成随机整数的运算学习
public class Zheng { int a=0,b=0,c=0; int result=0,g=0; String s=null; public void Zheng(){ a = (int)(Math.random()*100);//生成0-99的随机数 b = (int)(Math.random()*100); c = (int)(Math.random()*4);//生成0-3的随机数,用来随机产生运算符 if(c==0){ System.out.println(a+"+"+b+"="); result = a + b; } if(c==1){ System.out.println(a+"-"+b+"="); result = a - b; } if(c==2){ System.out.println(a+"*"+b+"="); result = a * b; } if(c==3){ if(b==0){ while(b==0) b=(int)(Math.random()*10);//防止分母为0 } else{ System.out.println(a+"/"+b+"="); int smaller = a > b ? b : a;//将a与b中的最小值赋给变量 for (int i = 1; i <= smaller; i++) { if (a % i == 0 && b % i == 0) { g = i; }//求a与b的最大公因子 } a = a/g; b = b/g; s = a+"/"+b; } } } }
//实现四则运算spa
import java.util.*; public class YunSuan { public static void main (String args[]){ int x,z=0; Zheng zheng = new Zheng(); System.out.print("请输入要生成的题目数:"); Scanner reader = new Scanner(System.in); int n = reader.nextInt(); Random random = new Random(); for(int i=1;i<n+1;i++){ for(;;){ System.out.println("题目"+i+":"); zheng.Zheng(); System.out.print("请输入结果:"); if(zheng.c==3){ Scanner sc=new Scanner(System.in); String s =new String(); s =sc.nextLine(); if(s.equals(zheng.s)){ z++; System.out.println("此题正确"); } else System.out.println("此题错误,正确答案为:"+zheng.s); } else{ x =reader.nextInt(); if(x==zheng.result){ z++; System.out.println("此题正确"); } else System.out.println("此题错误,正确答案为:"+zheng.result); } break; } } int o =(int)(((double)z/(double)n)*100);//计算正确率 System.out.print("完成"+n+"道题,正确数目为:"+z+",正确率为:"); System.out.printf("%d",o); System.out.println("%"); } }
简单四则运算码云连接:连接命令行
考虑到多种因素后设计
当发现须要考虑括号、运算优先级以及多个数字计算的因素时,发现事情没那么简单,而后疯狂脑阔疼.........,在看到栈以及中缀转后缀等问题后,陷入了沉思,在经过长时间的学习和理解后才知道如何解决括号与计算问题,以前没有这些知识前,根本无从下手,经过最终地艰苦奋斗仍是设计出代码,可是仍是有些问题,代码以下:code
//生成随机数
import java.util.*; public class RandomNum { int RandomNum(int x){ int num =(int)(Math.random()*x); return num; } } //生成随机运算符 import java.util.*; public class RandomChar { char RandomChar(){ int num = (int)(Math.random()*4); switch (num){ case 0:return'+'; case 1:return'-'; case 2:return'*'; case 3:return'÷'; default:return 0; } } }
//生成中缀表达式以及产生题目
import java.util.*; public class Produce { void Produce(int n){ RandomNum num = new RandomNum(); RandomChar c = new RandomChar(); Scanner reader = new Scanner(System.in); String s = ""; String d = ""; String g = ""; String out = "";//最终的中缀表达式 String end = "";//转化后的后缀表达式 int count = 0;//记录作对的题目个数 for(int i=1;i<n+1;i++){ System.out.println("题目"+i+":"); int a = (int)(Math.random()*5+1); int amount = num.RandomNum(a)+1;//记录随机产生运算符的个数 for(int j=0;j<amount;j++){ s = s+c.RandomChar()+" "; } String str[] = s.split(" ");//将字符串转化成字符串数组 for(int z=0;z<str.length;z++){ d = d+num.RandomNum(50)+str[z]; } d = d + num.RandomNum(50); switch((num.RandomNum(2))){ case 0: System.out.println(d+" = ");//输出不带括号的中缀表达式 break; case 1: for(int k=0;k<str.length;k++){ g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k]; }//在中缀表达式中加入括号 g = g + num.RandomNum(50); System.out.println(g+" = ");//输出不带括号的中缀表达式 break; } out = g; out = d; int p = 0;//初始化最终获得的答案 infixToSuffix in = new infixToSuffix(); end = in.infixToSuffix(out);//将中缀表达式转化为后缀表达式 suffixToArithmetic ex = new suffixToArithmetic(); p = (int) ex.suffixToArithmetic(end);//计算后缀表达式的结果 System.out.print("请输入结果:"); int x = reader.nextInt(); if(x==p){ System.out.println("结果正确!"); count++; } else{ System.out.println("结果错误,正确结果是:"+p); } s=""; g=""; d=""; } int result = (int)(((double)count/(double)n)*100);//计算正确率 System.out.println("总共答题"+n+"道,正确率为:"+result+"%"); } }
//将中缀表达式转化为后缀表达式
import java.util.*; public class infixToSuffix { public static String infixToSuffix(String infix) { Stack<Character> stack = new Stack<Character>(); String suffix = ""; int length = infix.length(); for (int i = 0; i < length; i++) { Character temp; char c = infix.charAt(i); switch (c) { // 忽略空格 case ' ': break; // 碰到'(',push到栈 case '(': stack.push(c); break; // 碰到'+''-',将栈中全部运算符弹出,送到输出队列中 case '+': case '-': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(') { stack.push('('); break; } suffix += " " + temp; } stack.push(c); suffix += " "; break; // 碰到'*''/',将栈中全部乘除运算符弹出,送到输出队列中 case '*': case '/': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(' || temp == '+' || temp == '-') { stack.push(temp); break; } else { suffix += " " + temp; } } stack.push(c); suffix += " "; break; // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符所有依次弹出,送至输出队列后,再丢弃左括号 case ')': while (stack.size() != 0) { temp = stack.pop(); if (temp == '(') break; else suffix += " " + temp; } // suffix += " "; break; //若是是数字,直接送至输出序列 default: suffix += c; } } //若是栈不为空,把剩余的运算符依次弹出,送至输出序列。 while (stack.size() != 0) { suffix += " " + stack.pop(); } return suffix; } }
//计算后缀表达式的值
import java.util.*; public class suffixToArithmetic{ int suffixToArithmetic(String h) { Stack<Integer>stack = new Stack<Integer>(); String b[] = h.split(" ");//将字符串转化为字符串数组 for(int i=0;i<b.length;i++){ String c = b[i]; if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){ int y = stack.pop(); int x = stack.pop(); Caculate z = new Caculate(); stack.push(z.Caculate(x,y,c));//将运算结果从新压入栈 }//是运算符,弹出运算数,计算结果 else{ stack.push(Integer.valueOf(c)); } } return stack.pop();//弹出栈顶元素就是运算最终结果 } }
//断定运算符并进行运算
class Caculate{ int Caculate(int x,int y,String c) { if (c.equals("+")) return x + y; if (c.equals("-")) return x - y; if (c.equals("*")) return x * y; if (c.equals("/")){ if(x<=y||x==0) return 1; else return x / y; } return 0; } }
完善后四则运算码云连接:连接
3、总结分析与运行截图
结对项目总结与分析
开始觉得项目应该很快就能完成,发现缺乏好多知识后就很难完成这个项目,不得不将新知识学习后再进行编程,在编程中遇到往中缀表达式加入括号的问题,以及除法计算的问题,遇到左右括号数量不等的状况,遇到括号只括住一个数字或者一个运算符的问题,遇到碰见除法没法输出的问题,遇到没法计算出结果的问题,这些问题都在最后与同伴的讨论中获得部分解决,仍是有些问题没有获得解决。程序的UML图将在完善程序后的博客中体现。 除法计算问题的截图:
运行截图体现
简单四则运算的运行截图:
部分完善后的运行截图:
4、结对同伴的评价
结对同伴陈敬勇在完成这次项目中的表现很是出色,咱们在遇到问题后都能认真讨论得出答案,避免了一我的完成任务时的思惟定式的问题,咱们相互鼓励支持,相信在下来的完善代码问题的过程当中,咱们会作的更好。