热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java生成算数表达式_惊!小学生要失业了,Java实现生成并计算四则运算表达式。...

githup传送门:https:github.comBubblegodFormulationCalculation项目成员:梁竞袁智杰1、项目要求题目:

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、设计实现过程

5ff5c1cc36e7b34360d73d5d6a295fb2.png

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

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 &#61; 0; i <&#61; randomNumber_fraction; i&#43;&#43;) {inttemp;

Random randomTemp&#61; newRandom();

temp&#61; randomTemp.nextInt(randomNumber_integer &#43; 1);

position[i]&#61;temp;

}

}voidsignListGenerating() {inti;for (i &#61; 0; i

Random randomTemp&#61; newRandom();

temp&#61; randomTemp.nextInt(4);if (temp &#61;&#61; 0) {

signList.add("&#43;");

}else if (temp &#61;&#61; 1) {

signList.add("-");

}else if (temp &#61;&#61; 2) {

signList.add("*");

}else{

signList.add("÷");

}

}

}

第二部分&#xff1a;将中缀表达式转化成后缀表达式

public staticString infixToSuffix(String infixExpression) {//创建操作符堆栈

Stack characterStack &#61; new Stack();//要输出的后缀表达式字符串

String suffix &#61; "";//传入的中缀表达式的长度

int length &#61;infixExpression.length();for (int i &#61; 0; i

chartemp;//获取该中缀表达式中的每一个字符并进行相对应的判断

char ch &#61;infixExpression.charAt(i);switch(ch) {//忽略空格

case &#39; &#39;:break;//如果是左括号直接压入栈中

case &#39;(&#39;:

characterStack.push(ch);break;//碰到&#39;&#43;&#39; &#39;-&#39;&#xff0c;将栈中的所有运算符全部弹出去&#xff0c;直至碰到左括号为止&#xff0c;输出到队列中去

case &#39;&#43;&#39;:case &#39;-&#39;:while (characterStack.size() !&#61; 0) {

temp&#61;characterStack.pop();if (temp &#61;&#61; &#39;(&#39;) {//如果推出来的那个字符刚好是左括号&#xff0c;那么就重新将左括号放回栈中&#xff0c;并终止循环

characterStack.push(&#39;(&#39;);break;

}

suffix&#43;&#61;temp;

}//没有进入循环说明当前为第一次进入或者前面运算都有括号等情况所导致//将当前符号压入栈中

characterStack.push(ch);

suffix&#43;&#61; "#";break;//如果是乘号或者除号&#xff0c;则弹出栈中所有运算符&#xff0c;直到碰到加号、减号、左括号为止&#xff0c;最后将该运算符压入栈中

case &#39;*&#39;:case &#39;÷&#39;:while (characterStack.size() !&#61; 0) {

temp&#61;characterStack.pop();//只有比当前优先级高的或者相等的才会弹出到输出队列&#xff0c;遇到加减左括号&#xff0c;直接停止当前循环

if (temp &#61;&#61; &#39;&#43;&#39; || temp &#61;&#61; &#39;-&#39; || temp &#61;&#61; &#39;(&#39;) {

characterStack.push(temp);break;

}else{

suffix&#43;&#61;temp;

}

}//没有进入循环说明当前为第一次进入或者前面运算都有括号等情况所导致//将当前符号压入栈中

characterStack.push(ch);

suffix&#43;&#61; "#";break;//如果碰到的是右括号&#xff0c;则距离栈顶的第一个左括号上面的所有运算符将被弹出栈并抛弃左括号(既不需要将左括号输出到队列中也不需要将右括号压入栈中)

case &#39;)&#39;:while (!characterStack.isEmpty()) {

temp&#61;characterStack.pop();if (temp &#61;&#61; &#39;(&#39;) {break;

}else{

suffix&#43;&#61;temp;

}

}break;//默认情况&#xff0c;如果读取到的是操作数&#xff0c;则直接送至输出队列

default:

suffix&#43;&#61;ch;break;

}

}//最后如果栈中依然还有运算符的话&#xff0c;则把剩余运算符一次弹出&#xff0c;送至输出序列

while (characterStack.size() !&#61; 0) {

suffix&#43;&#61;characterStack.pop();

}returnsuffix;

}

第三部分&#xff1a;将后缀表达式转化成二叉树&#xff0c;利用二叉树的优先级&#xff0c;将同等级的运算数进行排序&#xff0c;从而把中缀表达式不相同的的式子&#xff0c;转化成为后缀表达式一样的式子&#xff0c;便可找出重复的式子&#xff0c;并剔除掉。

/*** function&#xff1a;优化策略一(按规则优化二叉树&#xff0c;使其计算过程中不会出现负数)

*

*&#64;paramtree

*&#64;return

*/

publicBinaryTree adjustmentTree(BinaryTree tree) {if (tree !&#61; null) {

String leftValue&#61;getTreeValue(tree.getLeftTree());

String rightValue&#61;getTreeValue(tree.getRightTree());//若右子树的值大于左子树&#xff0c;则交换子树

if (rightValue.equals("") || leftValue.equals("")) {//表示此时已经递归到叶子了&#xff0c;直接返回即可

returntree;

}else if (dataOperation.calculateData(rightValue, leftValue, "?").equals("1")) {

tree&#61;swapChildTree(tree);

}

tree.setLeftTree(adjustmentTree(tree.getLeftTree()));

tree.setRightTree(adjustmentTree(tree.getRightTree()));

}returntree;

}/*** function&#xff1a;优化策略二(中序遍历二叉树&#xff0c;转化为符合预定运算顺序的带括号的表达式)

*

*&#64;paramtree

*&#64;return

*/

publicString treeToExpression(BinaryTree tree) {

String left&#61; "";

String right&#61; "";

String expression&#61; "";if (tree !&#61; null) {if (tree.getLeftTree() !&#61; null && tree.getRightTree() !&#61; null) {

String leftRoot&#61;tree.getLeftTree().getRootData();

String rightRoot&#61;tree.getRightTree().getRootData();if (leftRoot.equals("&#43;") || leftRoot.equals("-") || leftRoot.equals("*") || leftRoot.equals("÷")) {

left&#61; "(" &#43; treeToExpression(tree.getLeftTree()) &#43; ")";

}else{

left&#61;treeToExpression(tree.getLeftTree());

}if (rightRoot.equals("&#43;") || rightRoot.equals("-") || rightRoot.equals("*") || rightRoot.equals("÷")) {

right&#61; "(" &#43; treeToExpression(tree.getRightTree()) &#43; ")";

}else{

right&#61;treeToExpression(tree.getRightTree());

}

}

expression&#61; left &#43; tree.getRootData() &#43;right;

}returnexpression;

}

5、测试运行

这是题目生成个数100个&#xff0c;数值范围是10的情况

0e2122626cfff3d046f08b3461de0d9b.png

f5617e4835a437890adefe36bf33fbb2.png

092eee59c01801751c258b5cc92c6cfd.png

这是生成题目10000条的情况&#xff0c;经过大量的测试&#xff0c;发现。。。。。

5c676f5ed207120758733fa9a22d95ee.png

22a5e5ae7fa5fb486b0135c3032d7448.png

ec50549f71b53d71add168099af4d398.png



推荐阅读
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • 本文介绍了在Go语言中可见性与scope的规则,包括在函数内外声明的可见性、命名规范和命名风格,以及变量声明和短变量声明的语法。同时,还介绍了变量的生命周期,包括包级别变量和局部变量的生命周期,以及变量在堆和栈上分配的规则和逃逸分析的概念。 ... [详细]
  • Iwanttointegratesort,order,maxandoffsetinafindAllquery.Thefollowingworksfine:我想在fin ... [详细]
  • https:github.comdarcyclarkeFront-end-Developer-Interview-QuestionstreemasterChinese#refere ... [详细]
author-avatar
碧桃玉李
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有