java加减乘除运算顺序_java 实现加减乘除混合运算
初衷:解决小学一年级到四年级 基本加减乘除混合运算
基本思路:
表达式:100+3+2-200+(10000/5+(100/2))
此类表达式我们称之为中缀表达式(运算符在数字的中间),如果我们稍加转换,转化为
100, 3, +, 2, +, 200, -, 10000, 5, /, 100, 2, /, +, + 转化后的表达式我们称之为后缀表达式(运算符在数字的后面),先不考虑该表达式是怎么来的,后面我们将详细介绍由中缀表达式转化为后缀表达式的实现过程;我们借助栈的数据结构(后进先出)来辅助我们解决这个问题,拿到转化后的结果 我们先创建一个空栈,从左往右开始运算,具体的运算逻辑为:
1.遇到数字则入栈
2.遇到运算符号 则将栈顶两元素出栈
3.根据运算符号进行运算并将运算结果入栈
4.表达式结束 则将栈顶元素 取出
我们先靠手来计算一下结果为1955;现在我们用这个规律来进行分析,
第一步:数字100先入栈;
第二步:数字3入栈;
第三步: + 则将栈顶的数字3取出,此时栈顶为100 再将数字100取出,将相加后的结果103入栈;
第四步:数字2入栈;
第五步:+ 将栈顶数字2取出,继续取出栈顶数字103,将相加后的结果105入栈;
第六步:200入栈;
第七步:- 将栈顶数字200 取出,继续取出栈顶数字105 将相减后结果 -95 入栈;
第八步:数字10000入栈;
第九步:数字5入栈;
第十步:/ 将栈顶数字5 取出 继续取出栈顶数字10000,计算结果为2000,将2000入栈;
第十一步:数字100入栈;
第十二步:数字2入栈;
第十三步:/ 栈顶数字 2 和栈顶数字100 结果为50 入栈;
第十四步:+ 栈顶数字50 和栈顶数字 2000 计算结果为2050 入栈;
第十五步:+ 栈顶数字2050 和栈顶数字-95 计算结果为 1955 入栈;
第十六步:遍历结束,取出栈顶数字 1955
至此结果已经出来了,最终的计算结果为1955
现在来解释刚刚的疑问,后缀表达式该怎么来生成呢??
好了现在我们来一点一点解开未解之谜
1.中缀表达式从左往右遍历,遇到数字则输出
2. 遇到左括号,入栈;遇到右括号 则从栈顶取 一直到取到左括号为止;遇到运算符,优先级不低于当前符号出栈并输出,直到取到比当前优先级低为止(+,-优先级相等,* / 优先级相等,+- 优先级低于 * /)
3.表达式遍历结束 栈内符号依次出栈
还是刚刚的表达式:100+3+2-200+(10000/5+(100/2))
我们来按照这个步骤来分析一下
先创建一个空栈
第一步:数字100输出;
第二步:+ 入栈;
第三步:数字3 输出;
第四步:+ 栈中没有优先级比+低 故栈中+出栈输出,此处+入栈;
第五步:数字2输出;
第六步:- 栈中没有优先级比-低 故栈中+出栈输出,此处-入栈;
第七步:数字200 输出;
第八步:+ 栈中没有优先级比+低 故栈中-出栈输出,此处+ 入栈;
第九步:符号(入栈;
第十步:数字10000输出;
第十一步:/ 栈中+ (优先级都没有/ 高 故/入栈;
第十二步:数字5 输出;
第十三步:+ 栈顶为/ 优先级高于+ 故+ 入栈/出栈输出;
第十四步:(入栈;
第十五步:数字 100 输出;
第十六步:/ 栈顶为( 此处/入栈;
第十七步:数字2 输出;
第十八步:),找到栈顶最近的(之间的符号/出栈输出,(出栈;
第十九步:),到最近的(之间的符号+出栈输出,(出栈;
第二十步:遍历结束,栈中依次出栈+;
从上往下 背景标红部分为后缀表达式的输出顺序
下面为java代码实现 仅供参考
package com.fx.hfirst.strategy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Pattern;
public class Compute {
/**
* @param args
*/
public static void main(String[] args) {
String data = "100+3+2-200+(10000/5+(100/2))";
String[] dataArray = getDataArray(data);
String[] postfixArray = getPostFix(dataArray);
computeWithPostFix(postfixArray);
}
private static String[] getDataArray(String data) {
if (data == null || "".equals(data.trim()) || data.trim().length() < 1) {
return null;
}
int dataLength = data.length();
String[] dataArray = new String[dataLength];// 根据字符串的长度创建数组
int top = 0;
String numStr = "";
for (int i = 0; i < dataLength; i++) {
char datai = data.charAt(i);
String num = String.valueOf(datai);
if (isNum(num)) {// 数字
numStr += num;
if (i + 1 == dataLength) {
dataArray[top] = numStr;
top++;
}
} else {
if (!"".equals(numStr)) {// numStr 存在
dataArray[top] = numStr;// 数字存放到结果数组中
numStr = "";// 还原
top++;// 指针下移
}
// 符号
dataArray[top] = num;
top++;// 指针下移
}
}
return removeNull(dataArray, top);
}
/**
* 获取后缀表达式
*
* @param data
* @return
*/
private static String[] getPostFix(String[] dataArray) {
if (dataArray == null || dataArray.length < 1) {
return null;
}
// 1.遍历数组 数字输出
// 2.若是符号 则判断和栈顶符号的优先级 是右括号 或者优先级低于栈顶符号(乘除高于加减)则栈顶元素依次出栈 输出 并将当前符号入栈
// 3.数组结束 栈内符号依次出栈
int dataLength = dataArray.length;
Stack dataStack = new Stack();
String[] dataBuffer = new String[dataLength];
int top = 0;
for (int i = 0; i < dataLength; i++) {
String datai = dataArray[i];
if (isNum(datai)) {// 数字
dataBuffer[top] = datai;
top++;// 指针下移
} else if (isLeftBracket(datai)) {// 左括号
dataStack.push(datai);// 压栈
} else if (ComputeEnum.isCompute(datai)) {// 运算符
List lessThenMeList = getNotLessThenMeta(dataStack,
datai);
if (lessThenMeList != null && !lessThenMeList.isEmpty()) {
for (String lessThen : lessThenMeList) {// 小于当前运算符的符号输出
dataBuffer[top] = lessThen;
top++;// 指针下移
}
}
dataStack.push(datai);// 当前元素入栈
} else if (isRightBracket(datai)) {// 右括号 查找到最近左括号之间的所有符号 出栈
List betweenLeftBracketList = getBetweenLeftBracketMeta(dataStack);
if (betweenLeftBracketList != null
&& !betweenLeftBracketList.isEmpty()) {
for (String between : betweenLeftBracketList) {// 小于当前运算符的符号输出
dataBuffer[top] = between;
top++;// 指针下移
}
}
} else {
System.err.println("请注意中英文符号,检查出包含不支持的运算符!");
return null;
}
}
while (!dataStack.isEmpty()) {
dataBuffer[top] = dataStack.pop();
top++;// 指针下移
}
return removeNull(dataBuffer, top);
}
// 根据后缀表达式计算出结果 并打印
private static void computeWithPostFix(String[] postfixArray) {
if (postfixArray == null || postfixArray.length < 1) {
System.err.println("postfixArray is null !");
return;
}
// 1.遇到数字则入栈
// 2.遇到运算符号 则将栈顶两元素出栈
// 3.将运算结果入栈
// 4.数组遍历结束 将栈顶元素 取出
Stack stack = new Stack();
for (String meta : postfixArray) {
if (isNum(meta)) {// 数字
stack.push(meta);
} else if (ComputeEnum.isCompute(meta)) {// 运算符号
double pop = Double.parseDouble(stack.pop());
double popNext = Double.parseDouble(stack.pop());
double result = compute(pop, popNext, meta);
stack.push(String.valueOf(result));
}
}
System.out.println("运算结果为:" + stack.pop());
}
private static double compute(double pop, double popNext, String meta) {
double result = 0;
ComputeEnum compute = ComputeEnum.get(meta);
switch (compute) {
case plus:// 加
result = popNext + pop;
break;
case minus:// 减
result = popNext - pop;
break;
case multiply:// 乘
result = popNext * pop;
break;
case divide:// 除
if ((pop < 0.000000001) && (pop > -0.000000001)) {
System.err.println("被除数不能为0!");
break;
}
result = popNext / pop;
break;
}
return result;
}
private static List getBetweenLeftBracketMeta(
Stack dataStack) {
if (dataStack == null || dataStack.size() < 1) {
return null;
}
List list = new ArrayList(dataStack.size());
while (!dataStack.isEmpty()) {
String pop = dataStack.pop();// 栈顶元素出栈
if (isLeftBracket(pop)) {
break;
}
list.add(pop);
}
return list;
}
/**
* 取出所有不比自己优先级低的元素
*
* @param dataStack
* @param datai
* @return
*/
private static List getNotLessThenMeta(Stack dataStack,
String datai) {
if (dataStack == null || dataStack.size() < 1) {
return null;
}
ComputeEnum computei = ComputeEnum.get(datai);
List list = new ArrayList(dataStack.size());
while (!dataStack.isEmpty()) {
String pop = dataStack.peek();// 栈顶元素
ComputeEnum compute = ComputeEnum.get(pop);
if (compute == null) {
break;
}
if (compute.level < computei.level) {
break;
} else {// 优先级高于当前符号 出栈
dataStack.pop();
list.add(pop);
}
}
return list;
}
private static String[] removeNull(String[] dataArray, int size) {
String[] dataResult = new String[size];
System.arraycopy(dataArray, 0, dataResult, 0, dataResult.length);
return dataResult;
}
private static boolean isNum(String num) {
String reg = "^\\d+$";
return Pattern.compile(reg).matcher(num).find();
}
/**
* 左括号
*
* @param num
* @return
*/
private static boolean isLeftBracket(String num) {
return "(".equals(num);
}
/**
* 右括号
*
* @param num
* @return
*/
private static boolean isRightBracket(String num) {
return ")".equals(num);
}
}
enum ComputeEnum {
plus("+", 0), // 加法
minus("-", 0), // 减法
multiply("*", 1), // 乘法
divide("/", 1), // 除法
;
private static Map dataMap = new HashMap();
static {
dataMap.put(plus.code, plus);
dataMap.put(minus.code, minus);
dataMap.put(multiply.code, multiply);
dataMap.put(divide.code, divide);
}
public String code;
public int level;
private ComputeEnum(String code, int level) {
this.code = code;
this.level = level;
}
public static ComputeEnum get(String code) {
return dataMap.get(code);
}
public static boolean isCompute(String code) {
return dataMap.containsKey(code);
}
}
博客中若有错误,欢迎指正,我们一起来共同完善!
java加减乘除运算顺序_java 实现加减乘除混合运算相关推荐
- java 四则混合运算_Java实现四则混合运算代码示例
使用栈来实现,可以处理运算优先级. 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2.无需把表达式先转换为逆波兰等形式. package com.joshua.cal; import j ...
- java四则混合运算_Java实现四则混合运算代码示例
使用栈来实现,可以处理运算优先级. 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2.无需把表达式先转换为逆波兰等形式. package com.joshua.cal; import j ...
- java类初始化顺序_Java 类的初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次 构造代码块:类中直接用{}定义,每一次创建对象时执行 执行顺序优先级:静态块,main(),构造块,构造方法 1. 构造函数 publi ...
- 分数混合运算简便方法_分数混合运算和简便运算
作业内容 教学内容 : 分数混合运算和简便运算. 教学目标 : 1.通过创设自主探究,尝试迁移.合作交流的探究情境,掌握分数混合运算和简便运算. 2.在观察.迁移.尝试练习.交流反馈等活动中,培养学生 ...
- 分数混合运算简便方法_分数混合运算和简便计算
学习目标知识与技能懂得分数混合运算的顺序和整数混合运算的顺序相同,能熟练进行有关分数混合运算的计算. 过程与方法 知道整数乘法的运算定律对于分数乘法同样适用,并能够运用所学运算定律进行一些简便运算. ...
- 分数混合运算简便方法_分数混合运算方法
<分数混合运算方法>由会员分享,可在线阅读,更多相关<分数混合运算方法(4页珍藏版)>请在人人文库网上搜索. 1.最新 料推荐分数混合运算[基础知识]1. 分数混合运算与整数混 ...
- c语言带括号整数四则混合运算,带中括号整数四则混合运算练习题.doc
带中括号整数四则混合运算练习题 精品文档2016全新精品资料-全新公文范文-全程指导写作 –独家原创 PAGE1 / NUMPAGES1 带中括号整数四则混合运算练习题 540÷﹙30×15÷50﹚× ...
- java a运算顺序_Java中计算顺序的规则是什么?
噜噜哒 让我说得很清楚,因为人们一直误解这一点:子表达式的求值顺序是独立结合性和优先级..关联性和优先级确定操作者被执行但是不要确定子表达式都是经过评估的.你的问题是关于子表达式都是经过评估的.考虑A ...
- java+实现集合并运算_JAVA程序设计报告+集合运算
JAVA程序设计报告+集合运算 JAVA程序设计报告集合的运算(交并差)学生学号专业信息工程(系统工程方向)院系信息与控制学院实习时间三周:指导老师陈金辉目录实验目的试验设计实验源程序程序设计调试不足 ...
最新文章
- [Springboot实战] 集成 Caffeine
- jquery选择器 之 获取父级元素、同级元素、子元素
- 基本概念之运算符与表达式
- LeetCode-链表-142. 环形链表 II
- Oracle怎么算开始一个会话,oracle – 随机获取ORA-08177只有一个活动会话
- 使用ImageMagick 在图片上绘制粗斜体的中文也许是一个错误。
- 服务发现与健康监测框架Consul-DNS转发的应用
- 我们去的地方一定会有屎
- docker 镜像 增删改查
- Zabbix 监控之 修改管理员用户密码
- 云课堂智慧职教网页版登录入口_云课堂智慧职教网页版
- python数据清洗代码_微博数据清洗(Python版)
- chemdraw如何改中文_如何修改ChemDraw的默认输出格式
- 缓存的使用以及出现的问题
- 虚地址到实地址的翻译过程
- PCB+SMT线上报价系统,数字化建设如何获取现金流?
- java 虚拟机优化
- 网络电话服务器安全认证管理系统,CA 数字证书认证系统建设解决方案
- 期间成本法与销售成本法
- B2B2C分布式微服务电商源码(支持:小程序、公众号、H5、IOS、Android)