Java 表达式的计算
来源:互联网 发布:it实用技巧 编辑:程序博客网 时间:2024/05/11 02:09
表达式的计算是指求诸如(34+2)*4*2+7
表达式的值,因为涉及到括号和算符优先级,如果直接进行计算比较麻烦,按照(34+2)*4*2+7
正常的顺序成为中缀表达式,在计算表达式式先转换为后缀表达式比较方便,(34+2)*4*2+7
的后缀表达式为34 2 + 4 * 2 * 7 +
。
求解表达式的过程有两步:
1、将表达式转换为后缀,
2、利用后缀求表达式值。
一、首先介绍将中缀表达式转换为后缀的算法:
首先定义运算符之间的优先级,每个运算符有两个优先级:栈(stack)内优先级,栈外优先级,分别用isp和icp表示。下面一张图是殷人昆版数据结构的优先级表,很准确。
优先级表可以简单的概括为,遇到’(‘进栈,遇到’)‘出栈,*和/优先级,以及+和/之间优先级自左到右,*/优先级大于+-优先级
在转换过程中设立操作符栈,如果读到的是数字直接输出,如果读到的是操作符,则考虑是否要进栈,如果读到的字符的栈外优先级大于栈顶的字符的栈内优先级,则进栈;否则栈顶操作符出栈并输出,再比较出栈操作后的栈顶元素的优先级,直到遇到一个栈顶元素栈内优先级大于读到的操作符的栈外的优先级,或者栈为空为止,最后将读到的操作符进栈。
一、下面具体介绍算法,假设当前读到的字符为ch
:
1、若ch是操作数直接输出,读入下一个字符到ch
2、若ch是操作符,判断ch的优先级icp(栈外优先级)和当前位于栈顶的操作符op的优先级isp(栈内优先级):
1)若icp(ch)>isp(op),令ch进栈,读入下一个字符ch.2)若icp(ch)<isp(op),退栈并输出。3)若icp(ch)=isp(ch),退栈但是不输出,因为是括号,只有括号才能相等。
结束。输出即为后缀表达式。
二、利用后缀求表达式值。
同样需要设置一个栈,以34 2 + 4 * 2 * 7 +
为例,遇到数字时进栈,遇到操作符时取出栈顶的两个数,并进行相应的运算,比如遇到+
,则计算34+2,并将34+2的结果重新放入栈顶。最后栈顶的数即为最终的运算结果。
下面是一个java代码实现, middleToPost()
函数将中缀转换为后缀,calculate()
函数利用后缀求值:
package leetCode;import java.util.ArrayList;import java.util.Stack;public class Solution { //元素类,是为了防止数字大于10的情况,如34+2 class Ele{ public boolean isOp; public double num; public char op; } //将中缀转换为后缀,包含+ - ( ) * /数字 //规则:1、遇到数字输出 2、遇到操作符考虑是否进栈 //3、遇到“(”,进栈,遇到“)”,将操作符出栈,直到遇到“(”,且将后者出栈 public ArrayList<Ele> middleToPost(String s){ Stack<Ele> opStack = new Stack<Ele>(); s = s.replace(" ", ""); ArrayList<Ele> res = new ArrayList<Ele>(); for(int i=0;i<s.length();i++){ //getNext操作,寻找下一个有效的整数或操作符 char c = s.charAt(i); Ele ele = new Ele(); if(c>'9'||c<'0'){ ele.isOp = true; ele.op = c; }else{ String str = c+""; while(i+1<s.length() && s.charAt(i+1)<='9'&&s.charAt(i+1)>='0'){ str = str+s.charAt(i+1); i++; } ele.isOp = false; ele.num = Double.parseDouble(str); }//end if(!ele.isOp){ res.add(ele); }else{ switch(ele.op){ case '(': opStack.push(ele);break; case ')': while(opStack.peek().op!='('){ res.add(opStack.pop()); } opStack.pop(); break; case '/': // ‘/’ ‘*’处理方式一样 case '*': if(opStack.isEmpty()){ opStack.push(ele); }else{ while(!opStack.isEmpty() && (opStack.peek().op=='*' || opStack.peek().op=='/')){ res.add(opStack.pop()); } opStack.push(ele); } break; default: //处理 + - if(opStack.isEmpty()){ opStack.push(ele); }else{ while(!opStack.isEmpty()&&opStack.peek().op!='('){ res.add(opStack.pop()); } opStack.push(ele); } } } } while(!opStack.isEmpty()){ res.add(opStack.pop()); } return res; } //利用后缀表达式求值 public int calculate(String s) { ArrayList<Ele> eles = middleToPost(s); Stack<Double> stack = new Stack<Double>(); double top = 0.0; for(int i=0;i<eles.size();i++){ Ele e = eles.get(i); if(e.isOp){ if(e.op=='+'){ top= stack.pop()+stack.pop(); }else if(e.op=='-'){ double after = stack.pop(); double before = stack.pop(); top = before-after; }else if(e.op=='*'){ top = stack.pop()*stack.pop(); }else{ double after = stack.pop(); double before = stack.pop(); top = (int)before/(int)after; } stack.push(top); }else{ stack.push(e.num); } } return stack.peek().intValue(); } public static void main(String[] args) { Solution so = new Solution(); String s = "14/3*2"; ArrayList<Ele> list = so.middleToPost(s); //输出后缀表达式 for(int i=0;i<list.size();i++){ if(list.get(i).isOp) System.out.print(list.get(i).op+" "); else System.out.print(list.get(i).num+" "); } System.out.println(); //输出计算结果 System.out.println(so.calculate(s)); }}
- Java 表达式的计算
- java计算表达式的值
- Java中动态计算表达式的值
- Java中计算字符串表达式的好办法
- 字符串表达式的计算java版本
- Java实现简单的表达式计算
- Java解析字符串表达式--逆波兰表达式的计算
- (java)算术表达式的计算之后缀表达式
- java表达式计算
- 表达式计算java实现
- 表达式计算//java类
- 表达式计算//java类
- Java 简单表达式计算
- Java表达式计算-Fel
- JAVA 计算算式表达式
- java计算表达式
- 蓝桥杯 JAVA 表达式计算
- java字符串表达式计算
- 绝对详细!Nginx基本配置、性能优化指南
- 24. 使用GitHub
- C语言的基本输入与输出函数(全解)
- 排序算法系列之冒泡排序
- erlang笔记: 获取函数名,行号
- Java 表达式的计算
- Linux中实现无密码登陆----EXPECT
- 安卓GRIDVIEW,在部分VIEW被遮挡后,GRIDVIEW的CHILDCOUNT会减少
- Android 数据存储与读取:SQLite
- popToViewController用法
- 欢迎使用CSDN-markdown编辑器
- 25. 自定义Git
- Android基本控件之Button和ImageButton
- SylixOS JobQueue 简介