java生成算数表达式_惊!小学生要失业了,Java实现生成并计算四则运算表达式。...
githup传送门:https://github.com/Bubblegod/FormulationCalculation
项目成员:梁竞 袁智杰
1、项目要求
题目:实现一个自动生成小学四则运算题目的命令行程序。
需求:
1. 使用-n参数控制生成题目的个数。
2. 使用-r参数控制题目中数值(自然数、真分数和真分数分母)的范围。
3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2。
4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
5. 每道题目中出现的运算符个数不超过3个。
6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。
7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。
8. 程序应能支持一万道题目的生成。
9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。
2、PSP2.1表格
PSP2.1
Personal Software Process Stages
预估耗时(分钟)
实际耗时(分钟)
Planning
计划
20
40
· Estimate
· 估计这个任务需要多少时间
10
10
Development
开发
20
30
· Analysis
· 需求分析(包括学习新技术)
30
30
· Design Spec
· 生成设计文档
20
40
· Design Review
· 设计复审(和同事审核设计文档)
10
10
· Coding Standard
· 代码规范(为目前的开发制定合适的规范)
20
20
· Design
· 具体设计
20
40
· Coding
· 具体编码
400
600
· Code Review
· 代码复审
10
30
· Test
· 测试(自我测试,修改代码,提交修改)
30
30
Reporting
报告
30
50
· Test Report
· 测试报告
20
30
· Size Measurement
· 计算工作量
20
20
· Postmortem & Process Improvement Plan
· 事后总结,并提出过程改进计划
20
10
合计
680
990
3、设计实现过程
1.Mian类用于启动整个程序的所有操作。
2.BinaryTree类实现二叉树数据结构,以及所有二叉树操作的方法
3.ClaculateExpression类实现计算表达式的最终结果,并实现方法返回每条式子最终结果的答案
4.DataOperation对计算结果进行规范化(分数的格式化,若为假分数,统一化为带分数或整数格式,否则化为最简真分数)
5.ExprssionGenerator用于构造出最初的表达式
6.ExpressionOperation该类用来处理初步拼合而成的四则运算表达式,使其满足作业要求,并将初步拼合而成的四则运算表达式按照优化策略统一规范化,便于之后的查重处理
7.FileUtil用于处理文件的输入输出
4、代码说明
第一部分:等式的生成分为四个部分:
1.确定运算数的个数,符号数的个数
2.确定运算数的个数之后,确定整数与分数的个数
3.随机生成整数、分数、符号
4.把整数、分数、符号随机地,有序地排列组合,放入一个String的变量里面
voidintegerListGenerating() {inti;for (i = 0; i < randomNumber_integer; i++) {inttemp;
Random randomTemp= newRandom();
temp= randomTemp.nextInt(this.maximunValue);
integerList.add(Integer.toString(temp));
}
}voidfractionListGenerating() {inti;
i= 0;while (i
Random randomTemp1= newRandom();
Random randomTemp2= newRandom();
temp1= randomTemp1.nextInt(this.maximunValue - 1);
temp1+= 1;
temp2= randomTemp2.nextInt(this.maximunValue - 2);
temp2+= 2;if (!((temp1 % temp2 == 0) || (temp2 % temp1 == 0))) {
temp1= temp1 /getGCD(temp1, temp2);
temp2= temp2 /getGCD(temp1, temp2);if ((temp1 != temp2) && (temp1 != 0) && (temp2 != 0)) {if (temp1 >temp2) {
fractionList.add(Integer.toString(temp1/ temp2) + "`"
+ Integer.toString(temp1 % temp2) + "/"
+Integer.toString(temp2));
}else{
fractionList.add(Integer.toString(temp1)+ "/"
+Integer.toString(temp2));
}
i++;
}
}
}for (i = 0; i <= randomNumber_fraction; i++) {inttemp;
Random randomTemp= newRandom();
temp= randomTemp.nextInt(randomNumber_integer + 1);
position[i]=temp;
}
}voidsignListGenerating() {inti;for (i = 0; i < randomNumber_Number - 1; i++) {inttemp;
Random randomTemp= newRandom();
temp= randomTemp.nextInt(4);if (temp == 0) {
signList.add("+");
}else if (temp == 1) {
signList.add("-");
}else if (temp == 2) {
signList.add("*");
}else{
signList.add("÷");
}
}
}
第二部分:将中缀表达式转化成后缀表达式
public staticString infixToSuffix(String infixExpression) {//创建操作符堆栈
Stack characterStack = new Stack();//要输出的后缀表达式字符串
String suffix = "";//传入的中缀表达式的长度
int length =infixExpression.length();for (int i = 0; i < length; i++) {//临时字符变量
chartemp;//获取该中缀表达式中的每一个字符并进行相对应的判断
char ch =infixExpression.charAt(i);switch(ch) {//忽略空格
case ' ':break;//如果是左括号直接压入栈中
case '(':
characterStack.push(ch);break;//碰到'+' '-',将栈中的所有运算符全部弹出去,直至碰到左括号为止,输出到队列中去
case '+':case '-':while (characterStack.size() != 0) {
temp=characterStack.pop();if (temp == '(') {//如果推出来的那个字符刚好是左括号,那么就重新将左括号放回栈中,并终止循环
characterStack.push('(');break;
}
suffix+=temp;
}//没有进入循环说明当前为第一次进入或者前面运算都有括号等情况所导致//将当前符号压入栈中
characterStack.push(ch);
suffix+= "#";break;//如果是乘号或者除号,则弹出栈中所有运算符,直到碰到加号、减号、左括号为止,最后将该运算符压入栈中
case '*':case '÷':while (characterStack.size() != 0) {
temp=characterStack.pop();//只有比当前优先级高的或者相等的才会弹出到输出队列,遇到加减左括号,直接停止当前循环
if (temp == '+' || temp == '-' || temp == '(') {
characterStack.push(temp);break;
}else{
suffix+=temp;
}
}//没有进入循环说明当前为第一次进入或者前面运算都有括号等情况所导致//将当前符号压入栈中
characterStack.push(ch);
suffix+= "#";break;//如果碰到的是右括号,则距离栈顶的第一个左括号上面的所有运算符将被弹出栈并抛弃左括号(既不需要将左括号输出到队列中也不需要将右括号压入栈中)
case ')':while (!characterStack.isEmpty()) {
temp=characterStack.pop();if (temp == '(') {break;
}else{
suffix+=temp;
}
}break;//默认情况,如果读取到的是操作数,则直接送至输出队列
default:
suffix+=ch;break;
}
}//最后如果栈中依然还有运算符的话,则把剩余运算符一次弹出,送至输出序列
while (characterStack.size() != 0) {
suffix+=characterStack.pop();
}returnsuffix;
}
第三部分:将后缀表达式转化成二叉树,利用二叉树的优先级,将同等级的运算数进行排序,从而把中缀表达式不相同的的式子,转化成为后缀表达式一样的式子,便可找出重复的式子,并剔除掉。
/*** function:优化策略一(按规则优化二叉树,使其计算过程中不会出现负数)
*
*@paramtree
*@return
*/
publicBinaryTree adjustmentTree(BinaryTree tree) {if (tree != null) {
String leftValue=getTreeValue(tree.getLeftTree());
String rightValue=getTreeValue(tree.getRightTree());//若右子树的值大于左子树,则交换子树
if (rightValue.equals("") || leftValue.equals("")) {//表示此时已经递归到叶子了,直接返回即可
returntree;
}else if (dataOperation.calculateData(rightValue, leftValue, "?").equals("1")) {
tree=swapChildTree(tree);
}
tree.setLeftTree(adjustmentTree(tree.getLeftTree()));
tree.setRightTree(adjustmentTree(tree.getRightTree()));
}returntree;
}/*** function:优化策略二(中序遍历二叉树,转化为符合预定运算顺序的带括号的表达式)
*
*@paramtree
*@return
*/
publicString treeToExpression(BinaryTree tree) {
String left= "";
String right= "";
String expression= "";if (tree != null) {if (tree.getLeftTree() != null && tree.getRightTree() != null) {
String leftRoot=tree.getLeftTree().getRootData();
String rightRoot=tree.getRightTree().getRootData();if (leftRoot.equals("+") || leftRoot.equals("-") || leftRoot.equals("*") || leftRoot.equals("÷")) {
left= "(" + treeToExpression(tree.getLeftTree()) + ")";
}else{
left=treeToExpression(tree.getLeftTree());
}if (rightRoot.equals("+") || rightRoot.equals("-") || rightRoot.equals("*") || rightRoot.equals("÷")) {
right= "(" + treeToExpression(tree.getRightTree()) + ")";
}else{
right=treeToExpression(tree.getRightTree());
}
}
expression= left + tree.getRootData() +right;
}returnexpression;
}
5、测试运行
这是题目生成个数100个,数值范围是10的情况
这是生成题目10000条的情况,经过大量的测试,发现。。。。。
java生成算数表达式_惊!小学生要失业了,Java实现生成并计算四则运算表达式。...相关推荐
- java算术表达式_一文了解如何用 Java 进行算术表达式计算
(给ImportNew加星标,提高Java技能) 编译:ImportNew/唐尤华 如何用Java计算"5+3"."10-40"."10*3" ...
- c语言编程实现二进制计算器,本程序是用纯C语言编的一个基于命令行的四则运算计算器。主要用于计算四则运算表达式的值,同时可以实现四...
本程序是用纯C语言编的一个基于命令行的四则运算计算器.主要用于计算四则运算表达式的值,同时可以实现四 2016-08-22 0 0 0 暂无评分 其他 1 积分下载 如何获取积分? 本程序是用纯C语言 ...
- java生成pdf图表_开发员指南:使用Java图表转换为PDF/JPG等图像
Aspose.Cells for JavaExcel电子表格处理API,它允许Java开发人员在自己的Java应用程序中嵌入可读取.写入和操作Excel电子表格的能力,而无需依赖Microsoft E ...
- 为什么java中floatda正确_为什么cast to float在java中产生正确的结果?
文档没有特别好地解释,但 Double.toString(double)基本上在它产生的输出中执行一些舍入. Double.toString算法在整个Java SE中使用,包括例如System.out ...
- java基础代码实例_基础篇:详解JAVA对象实例化过程
1 对象的实例化过程 对象的实例化过程是分成两部分:类的加载初始化,对象的初始化 要创建类的对象实例需要先加载并初始化该类,main方法所在的类需要先加载和初始化 类初始化就是执行方法,对象实例化是执 ...
- java语言程序设计你_清华大学出版社-图书详情-《Java语言程序设计》
前言 Java语言是一种典型的面向对象的.跨平台的.支持分布式和多线程的优秀编程语言,具有极强的扩展性.自其诞生以来,迅速被业界认可并广泛应用于Web应用程序的开发中.在此形势下,国内高校在计算机及相 ...
- java编程最新图书_清华大学出版社-图书详情-《Java程序设计》
前言 Java是一种完全面向对象的程序设计语言,具有卓越的通用性.高效性.平台移植性和安全性,得到广泛的应用.在全球云计算和移动互联网产业高速发展的环境下,Java具备显著的优势和广阔前景.本书以Ja ...
- java执行python脚本_使用Runtime.getRuntime().exec()在java中调用python脚本
举例有一个Python脚本叫test.py,现在想要在Java里调用这个脚本.假定这个test.py里面使用了拓展的包,使得pythoninterpreter之类内嵌的编译器无法使用,那么只能采用ja ...
- java 内存溢出分析_用一段时间后java内存溢出问题分析(转)
几乎每个月都有出现因为内存溢出的问题,除了需要多分配内存外, 是不是要考虑对代码进行一些处理.. 下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1.尽量在合适的场合使用单例 使 ...
最新文章
- 【Java并发编程】面试必备之线程池
- 街头篮球服务器未响应,鹊桥相会《街头篮球》8.12七夕版本预告
- iOS - app 进行安全加固
- 检索数据_17_按照指定的次序返回查询结果
- 承载(Host)通用语言执行时
- java 8 并行_Java 8新特性之 并行和并行数组(八恶人-8)
- 2013蓝桥杯java试题_2013年第四届蓝桥杯javaB组 试题 答案 解析
- 【BZOJ2818】Gcd,数论练习之欧拉筛
- zabbix小结(一)zabbix概述
- android 优化
- 淘宝/天猫获取淘宝直播分类id接口 API 返回值说明
- GTX 1050ti和GTX960哪个好
- Leetcode 1647. Minimum Deletions to Make Character Frequencies Unique [Python]
- ubuntu12.04 显卡 散热
- Mac下Cornerstone错误异常导致打不开
- VMware workstation pro虚拟机以及linux操作系统的安装
- 通用计算机使用的内存条,笔记本内存和台式机内存能通用吗
- 【JZOJ3301】家族
- 抠图专题1:抠出白色陶瓷杯(每天一个PS小项目)
- 学术英语 | (11) WordList10