中缀表达式转后缀表达式
1. 概述
- 初始化两个栈:运算符栈s1和存储中间结果的栈s2
- 从左向有扫描中缀表达式
- 遇到操作数时将其压入s2
- 遇到运算符时,比较其与s1栈顶运算符的优先级:
- 如果s1为空,或栈顶元素为’(’,则将此运算符入栈
- 否则,若优先级比栈顶运算符的优先级高,则将运算符压入s1栈
- 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到1,与新的栈顶元素进行比较
- 遇到括号时:
- 如果是’(’,则直接压入s1
- 如果是’)’,则依次弹出s1栈顶的运算符,并压入s2,知道遇到’('为止,此时将这一对括号丢弃
- 重复以上步骤2至5,直到表达式的最右边
- 将s1中剩余的运算符依次弹出并压入s2
- 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
2. 举例
- 将中缀表达式1+((2+3)x4)-5转为后缀表达式
扫描到的元素 | s2(栈底–>栈顶) | s2(栈底–>栈顶) | 说明 |
---|
1 | 1 | 空 | 数字,直接入栈 |
+ | 1 | + | s1为空,运算符直接入栈 |
( | 1 | + ( | 左括号,直接入栈 |
( | 1 | + ( ( | 左括号,直接入栈 |
2 | 1 2 | + ( ( | 数字 |
+ | 1 2 | + ( ( + | s1栈顶为左括号,运算符直接入栈 |
3 | 1 2 3 | + ( ( + | 数字 |
) | 1 2 3 + | + ( | 右括号,弹出运算符压入s1直至遇到左括号 |
x | 1 2 3 + | + ( x | s1栈顶为左括号,运算符直接入栈 |
4 | 1 2 3 + 4 | + ( x | 数字 |
) | 1 2 3 + 4 x | + | 右括号,弹出运算符压入s1直至遇到左括号 |
- | 1 2 3 + 4 x + | - | -与+优先级相同,因此弹出+,再压入- |
5 | 1 2 3 + 4 x + 5 | - | 数字 |
到达最右端 | 1 2 3 + 4 x + 5 - | 空 | s1中剩余的运算符 |
3. 代码演示
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class Exception_Conversion {
public static void main(String[] args) {
String exception="1+((2+3)*4)-5";
List<String> s = exceptionList(exception);
System.out.println("中缀表达式:"+s);
List<String> list = parseSuffixExpresionList(s);
System.out.println("后缀表达式:"+list);
}
public static List<String> parseSuffixExpresionList(List<String> ls){
Stack<String> s1 = new Stack<>();
ArrayList<String> s2 = new ArrayList<>();
for (String item : ls) {
if(item.matches("\\d+")){
s2.add(item);
}else if(item.equals("(")){
s1.push(item);
}else if(item.equals(")")){
while(!s1.peek().equals("(")){
s2.add(s1.pop());
}
s1.pop();
}else{
while(!s1.empty()&&Operation.getPriority(s1.peek())>=Operation.getPriority(item)){
s2.add(s1.pop());
}
s1.push(item);
}
}
while(!s1.empty()){
s2.add(s1.pop());
}
return s2;
}
public static List<String> exceptionList(String str){
List<String> list = new ArrayList<>();
int i=0;
char c;
String s="";
while(i<str.length()){
c = str.substring(i, i + 1).charAt(0);
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'){
list.add(c+"");
}else{
s+=c;
if(i==str.length()-1){
list.add(s);
}else{
char c1 = str.substring(i+1, i + 2).charAt(0);
if(c1=='+'||c1=='-'||c1=='*'||c1=='/'||c1=='('||c1==')'){
list.add(s);
}
}
s="";
}
i++;
}
return list;
}
}
class Operation{
private static int ADD=1;
private static int SUB=1;
private static int MUL=2;
private static int DIV=2;
public static int getPriority(String operation){
int res=0;
switch (operation){
case "+":
res=ADD;
break;
case "-":
res=SUB;
break;
case "*":
res=MUL;
break;
case "/":
res=DIV;
break;
default:
break;
}
return res;
}
}