Java实现四则运算 谢雅淇 袁杏仪
Posted laura666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java实现四则运算 谢雅淇 袁杏仪相关的知识,希望对你有一定的参考价值。
https://github.com/3216004716/four-operations.git
项目相关要求
-
使用 -n 参数控制生成题目的个数,例如
Myapp.exe -n 10 将生成10个题目。
-
使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如
Myapp.exe -r 10
将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
-
生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 ? e2的子表达式,那么e1 ≥ e2。
-
生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
-
每道题目中出现的运算符个数不超过3个。
-
程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。
生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:
-
四则运算题目1
-
四则运算题目2
-
其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。
-
在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:
1.答案1
2.答案2
特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。
-
程序应能支持一万道题目的生成。
-
程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt
统计结果输出到文件Grade.txt,格式如下:
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。
PSP:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 15 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 15 |
Development | 开发 | 1160 | 1510 |
· Analysis | · 需求分析 (包括学习新技术) | 200 | 400 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 60 |
· Design | · 具体设计 | 60 | 90 |
· Coding | · 具体编码 | 600 | 700 |
· Code Review | · 代码复审 | 120 | 90 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 90 |
Reporting | 报告 | 120 | 150 |
· Test Report | · 测试报告 | 80 | 90 |
· Size Measurement | · 计算工作量 | 10 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 40 |
合计 | 1290 | 1675 |
解题思路:
-
取随机操作数
-
取随机操作符
-
生成表达式
-
由表达式转换为后缀表达式
-
后缀表达式入栈,计算
-
去重
-
结果写入文件
设计实现过程
-
Utils
-
RandomUtil 生成随机操作数和随机操作符
-
ExpressionUtil 生成表达式
-
CalculateUtil 封装计算的方法
-
FileUtil 生成题目和答案的文档
-
-
Calculate
-
calculateResult 用于计算结果
-
-
Expression
-
CheckExpression 检查重复的表达式
-
MyExpression 表达式类
-
PostfixExpression 生成后缀表达式
-
代码说明
-
RandomUtil类 获取随机操作数,用了Math.random()
// 获取随机操作数 public static String getRandomOperand(int range) { String Operand = null; int index = (int) (Math.random() * 4); if (index == 0) {// 生成分数 index = (int) (Math.random() * 3); if (index == 2) {// 生成假分数 Operand = getImproperTractionNumber(range); } else {// 生成真分数 Operand = getTruTractionNumber(range); } } else { Operand = getNaturalNumber(range);// 生成整数 } return Operand; }
-
ExpressionUtil类 获取随机表达式
public static MyExpression getRandomExpression(int range) { // 获取随机表达式 MyExpression myExpression = null; int index = (int) (Math.random() * 10); if (index <= 3) { myExpression = getOneOperExp(range);// 一个操作符 } else if (index == 4) {// 三个操作符 index = (int) (Math.random() * 2); if (index == 0) { myExpression = getThreeOperExp(range); } else { myExpression = getThreeOperExpWithBracket(range); } } else {// 两个操作符 index = (int) (Math.random() * 2); if (index == 0) { myExpression = getTwoOperExp(range); } else { myExpression = getTwoOperExpWithBracket(range); } } CaculateResult.caculate(myExpression); // 计算结果 ? return myExpression; }
-
PostfixExpression类 生成后缀表达式
private static ArrayList<String> generatePostfixExpression(String expression) { //生成String类型的后缀表达式 String[] expressionArray = expression.split(" "); ArrayList<String> postfixExpression = new ArrayList<String>(); Stack<String> stack = new Stack<String>(); for (int i = 0; i < expressionArray.length; i++) { String item = expressionArray[i]; String temp = ""; switch (item) { case "(": stack.push(item); break; case ")": while ((stack.size() != 0) && !((temp = stack.pop()).equals("("))) { postfixExpression.add(temp); } break; case "+": case "-": while ((stack.size() != 0) && !((temp = stack.pop()).equals("("))) { postfixExpression.add(temp); } if (temp.equals("(")) { stack.push(temp); } stack.push(item); break; case "×": case "÷": while ((stack.size() != 0) && !((temp = stack.pop()).equals("("))) { if (temp.equals("×") || temp.equals("÷")) { postfixExpression.add(temp); } else { stack.push(temp); break; } } if (temp.equals("(")) { stack.push(temp); } stack.push(item); break; default: postfixExpression.add(item); } } while (stack.size() != 0) { postfixExpression.add(stack.pop()); } return postfixExpression; }
-
CalculateResult类 计算后缀表达式
public class CaculateResult { public static void caculate(MyExpression myExpression) { PostfixExpression.toPostfixExpression(myExpression); ArrayList<String> postfixExpression = myExpression.getPostfixExpression(); String temp = ""; Stack<String> s = new Stack<>(); String rightOperand = null; String leftOperand = null; int result = 0; int a1, a2, b1, b2 = 0; int denominator = 0; int numerator = 0; a: for (int i = 0; i < postfixExpression.size(); i++) { String item = postfixExpression.get(i); switch (item) { case "+": rightOperand = s.pop(); leftOperand = s.pop(); if (CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { result = Integer.parseInt(rightOperand) + Integer.parseInt(leftOperand); temp = String.valueOf(result); } else if (CaculateUtil.isNumeric(rightOperand) && !CaculateUtil.isNumeric(leftOperand)) { denominator = CaculateUtil.getDenominator(leftOperand); numerator = CaculateUtil.getNumerator(leftOperand); numerator = Integer.parseInt(rightOperand) * denominator + numerator; temp = numerator + "/" + denominator; } else if (!CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { denominator = CaculateUtil.getDenominator(rightOperand); numerator = CaculateUtil.getNumerator(rightOperand); numerator = Integer.parseInt(leftOperand) * denominator + numerator; temp = numerator + "/" + denominator; } else { a1 = CaculateUtil.getDenominator(rightOperand); a2 = CaculateUtil.getNumerator(rightOperand); b1 = CaculateUtil.getDenominator(leftOperand); b2 = CaculateUtil.getNumerator(leftOperand); numerator = a1 * b2 + a2 * b1; denominator = a1 * b1; temp = numerator + "/" + denominator; } s.push(temp); break; case "×": rightOperand = s.pop(); leftOperand = s.pop(); if (CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { result = Integer.parseInt(rightOperand) * Integer.parseInt(leftOperand); temp = String.valueOf(result); } else if (CaculateUtil.isNumeric(rightOperand) && !CaculateUtil.isNumeric(leftOperand)) { numerator = CaculateUtil.getNumerator(leftOperand); denominator = CaculateUtil.getDenominator(leftOperand); numerator = numerator * Integer.parseInt(rightOperand); temp = numerator + "/" + denominator; } else if (!CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { numerator = CaculateUtil.getNumerator(rightOperand); denominator = CaculateUtil.getDenominator(rightOperand); numerator = numerator * Integer.parseInt(leftOperand); temp = numerator + "/" + denominator; } else { a1 = CaculateUtil.getDenominator(rightOperand); a2 = CaculateUtil.getNumerator(rightOperand); b1 = CaculateUtil.getDenominator(leftOperand); b2 = CaculateUtil.getNumerator(leftOperand); numerator = a2 * b2; denominator = a1 * b1; temp = numerator + "/" + denominator; } s.push(temp); break; case "-": leftOperand = s.pop(); rightOperand = s.pop(); int inta, intb = 0; if (CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { inta = Integer.parseInt(rightOperand); intb = Integer.parseInt(leftOperand); result = inta - intb; temp = String.valueOf(result); } else if (CaculateUtil.isNumeric(rightOperand) && !CaculateUtil.isNumeric(leftOperand)) { inta = Integer.parseInt(rightOperand); numerator = CaculateUtil.getNumerator(leftOperand); denominator = CaculateUtil.getDenominator(leftOperand); numerator = inta * denominator - numerator; temp = numerator + "/" + denominator; } else if (!CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { intb = Integer.parseInt(leftOperand); numerator = CaculateUtil.getNumerator(rightOperand); denominator = CaculateUtil.getDenominator(rightOperand); numerator = numerator - intb * denominator; temp = numerator + "/" + denominator; } else { a1 = CaculateUtil.getDenominator(rightOperand); a2 = CaculateUtil.getNumerator(rightOperand); b1 = CaculateUtil.getDenominator(leftOperand); b2 = CaculateUtil.getNumerator(leftOperand); numerator = a2 * b1 - a1 * b2; denominator = a1 * b1; temp = numerator + "/" + denominator; } if (temp.contains("-")||temp.equals("0")) { myExpression.setCheckAnswer(false); break a; } s.push(temp); break; case "÷": leftOperand = s.pop(); rightOperand = s.pop(); int integer_a = 0, integer_b = 0; if (CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { integer_a = Integer.parseInt(rightOperand); integer_b = Integer.parseInt(leftOperand); if (integer_b == 0) { break; } else if ((integer_a % integer_b) == 0) { result = integer_a / integer_b; temp = String.valueOf(result); } else { numerator = integer_a; denominator = integer_b; temp = numerator + "/" + denominator; } } else if (CaculateUtil.isNumeric(rightOperand) && !CaculateUtil.isNumeric(leftOperand)) { integer_a = Integer.parseInt(rightOperand); numerator = CaculateUtil.getNumerator(leftOperand); denominator = CaculateUtil.getDenominator(leftOperand); int temp1 = numerator; numerator = integer_a * denominator; denominator = temp1; temp = numerator + "/" + denominator; } else if (!CaculateUtil.isNumeric(rightOperand) && CaculateUtil.isNumeric(leftOperand)) { integer_b = Integer.parseInt(leftOperand); numerator = CaculateUtil.getNumerator(rightOperand); denominator = CaculateUtil.getDenominator(rightOperand); denominator = denominator * integer_b; temp = numerator + "/" + denominator; } else { a1 = CaculateUtil.getDenominator(rightOperand); a2 = CaculateUtil.getNumerator(rightOperand); b1 = CaculateUtil.getDenominator(leftOperand); b2 = CaculateUtil.getNumerator(leftOperand); numerator = a2 * b1; denominator = a1 * b2; temp = numerator + "/" + denominator; } s.push(temp); break; default: s.push(item); break; } } myExpression.setResult(CaculateUtil.reduceFractiong(temp)); } }
-
CheckExpression类 检查重复的表达式
public class CheckExpression { ? public static boolean checkRepeated(MyExpression expression1, MyExpression expression2) { boolean flag = true; if (expression1.getPostfixExpression().size() == expression2.getPostfixExpression().size()) { if (expToString(expression1.getPostfixExpression()).equals(expToString(expression2.getPostfixExpression())) || changePosition(expression1).equals(expToString(expression2.getPostfixExpression()))) { flag = false; } } return flag; } ? static String changePosition(MyExpression expression) { ArrayList<String> postfixExpression = expression.getPostfixExpression(); String firstOperator = getFirstOperator(postfixExpression); if (firstOperator.equals("+") || firstOperator.equals("×")) { int index = postfixExpression.indexOf(firstOperator); String temp = postfixExpression.get(index - 1); postfixExpression.set(index - 1, postfixExpression.get(index - 2)); postfixExpression.set(index - 2, temp); } ? return expToString(postfixExpression); } ? static String getFirstOperator(ArrayList<String> postfixExpression) { String operator = ""; for (int i = 0; i < postfixExpression.size(); i++) { String item = postfixExpression.get(i); if (item.equals("+") || item.equals("-") || item.equals("×") || item.equals("÷")) { operator = item; break; } } return operator; } ? public static String expToString(ArrayList<String> PostfixExpression) { String string = null; for (int i = 0; i < PostfixExpression.size(); i++) { string += PostfixExpression.get(i); } return string; } }
运行结果
项目小结
-
谢雅淇:我觉得这次程序的编写,我只是在为了解决问题而写方法的代码,没有很好地融入面向对象的思想。还有在写代码之前就要把思路理清楚,不然代码就会写的很乱,不仅会浪费时间,还会把代码写得非常冗长,可观性比较差。这次作业的结对队友,从讨论需求到编写代码的过程中都帮助了我很多,我觉得我需要提升的地方还有很多,以后还需要继续努力,多加练习。
-
袁杏仪:我觉得这次程序的编写,让我对开发程序有了更深入的了解,体会到沟通与合作的重要性,同时也感受到团队开发的乐趣,还收获了真挚的友谊。这次作业,让我感触最深的是我们写完代码后测试时,得出结果然后进行验算,检查出错答案并对源代码进行修改的过程,每一次修改,一步步得出正确的结果,这让我非常有成就感。
以上是关于Java实现四则运算 谢雅淇 袁杏仪的主要内容,如果未能解决你的问题,请参考以下文章