步骤
- 初始化两个栈,运算符s1和存储结果的栈s2
- 从左到右扫描中缀表达式
- 遇到操作数时,压入s2
- 遇到运算符时,比较与其s1栈顶运算符的优先级
1)如果s1为空,或栈顶运算符为左括号“*”,则直接将此运算符入栈
2)否则,若优先级比栈顶的高,也将运算符压入栈s1
3)否则,将s1的栈顶运算符弹出并压倒s2中再次转到 4.1与s1中新的栈顶运算符比较 - 若遇到括号
1)遇到左括号“(”直接压入s1
2)遇到右括号“)”一次弹出s1栈顶运算符,并压入s2 ,直到遇到左括号“(”,然后将这一对括号丢弃2 - 重复步骤2~5知到中缀表达式的最右边
- 将s1中剩余运算符一次弹出并压入s2
- 一次弹出s2的元素并输出 (其实s2只管压入并没有弹出过程 可以定义一个队列 或者一个list也可以的 )
- 这样就可以的到后缀表达式了 也叫逆波兰表达式
package com;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 中缀表达式转换为后缀表达式之后在计算
*
*
*
*/
public class BoLan {
public static void main(String[] args) {
String yunsuan = "33+2-5*63/(5-1)";
List<String> zhongZhui = toZhongZhui(yunsuan);
System.out.println(zhongZhui);
List<String> zhongZhuiToHouZhui = zhongZhuiToHouZhui(zhongZhui);
System.out.println("后缀表达式是" + zhongZhuiToHouZhui);
int houZhui = houZhui(zhongZhuiToHouZhui);
System.out.println("结果是" + houZhui);
}
/**
* 把算数表达式变为中缀
* @return
*/
public static List<String> toZhongZhui(String str) {
List<String> list = new ArrayList<>();
int i=0;
String num = "";
char c ;
if(str==null||"".equals(str)) {
return null;
}
do {
c=str.charAt(i);
if((c)<48||c>57) {
//处理多位数的一种办法
// if(!num.equals("")) {
// list.add(num);
// num = "";
// }
list.add(c+"");
i++;
}else {
//处理多位数数字的另一种方法
while(i<str.length()&&((c=str.charAt(i))>=48)&&((c=str.charAt(i))<=57)) {
num+=c;
i++;
}
list.add(num);
num = "";
}
}while(i<str.length());
return list;
}
/**
* 中缀转后缀
* @return
*/
public static List<String> zhongZhuiToHouZhui(List<String> list){
List<String> houzhui = new ArrayList<>();
Stack<String> sta = new Stack<>();
for(String l:list) {
if(l.matches("\\d+")) {
houzhui.add(l);
}else if(sta.size()==0||l.equals("(")) {
sta.push(l);
}else if(l.equals(")")){
while(!sta.peek().equals("(")){
houzhui.add(sta.pop());
}
sta.pop();
}
else {
while((!sta.isEmpty())&&youXianJi(l)<=youXianJi(sta.peek())) {
houzhui.add(sta.pop());
}
sta.push(l);
}
}
while(sta.size()!=0) {
houzhui.add(sta.pop());
}
return houzhui;
}
/**
* 判断优先级
*/
public static int youXianJi(String str) {
int a ;
switch (str) {
case "+":
a = 1;
break;
case "-":
a = 1;
break;
case "*":
a = 2;
break;
case "/":
a = 2;
break;
default:
System.out.println("没有这个符号");
a = -1;
break;
}
return a;
}
/**
* 计算后缀
*/
public static int houZhui(List<String> list) {
Stack<String> s = new Stack<>();
for(String str:list) {
if(str.matches("\\d+")) {
s.push(str);
}else {
int num2 = Integer.parseInt(s.pop());
int num1 = Integer.parseInt(s.pop());
int temp;
switch (str) {
case "+":
temp = num1+num2;
break;
case "-":
temp = num1-num2;
break;
case "*":
temp = num1*num2;
break;
case "/":
temp = num1/num2;
break;
default:
throw new RuntimeException("没有这个符号不能计算");
}
s.push(temp+"");
}
}
return Integer.parseInt(s.pop());
}
}