1.思路分析:
1.需要两个栈,一个符号栈和一个中间结果栈
2.遍历中缀表达式
3.遇到数字,直接入中间结果栈
4.遇到运算符
- 4.1 如果符号栈为空或者栈顶的元素为"(",则将当前运算符直接入符号栈
- 4.2 如果当前符号比栈顶符号优先级高,则将当前运算符压入符号栈
- 4.3 如果当前符号优先级比栈顶符号低或者相等,则将符号栈顶元素弹出并压入到中间结果栈中,最后将当前运算符压入到符号栈
5.遇到括号
- 如果是"(",则直接入栈
- 如果是")",则依次弹出符号栈中的元素,并压入到中间结果栈,直到遇到"(",把"("弹出,此时丢弃了一对小括号
6.重复2-5步,直到遍历到表达式最右边
7.将符号栈中剩余的元素依次弹出压入到中间结果栈中
8.最后将中间结果栈中的元素逆序就得到了后缀表达式,也就是逆波兰表达式
例子:
image.png
2.代码实现
//将中缀表达式转换成后缀表达式
public static List<String> toSuffixExpression(List<String> list){
//1.需要两个栈,一个符号栈,一个中间结果栈
Stack<String> stack = new Stack<>();
//因为中间结果栈只有入栈操作,且需要逆序输出,所以采用ArrayList更好一些
List<String> result = new ArrayList<>();
//2.遍历表达式
for(String item:list){
//3.如果是数字直接入中间符号栈
if(item.matches("\\d+")){
result.add(item);
}
//5.如果是括号
//5.1如果是左括号,直接入栈
else if(item.equals("(")){
stack.push(item);
}
//5.2如果是右括号,将符号栈中元素pop,并压入中间符号栈,直到遇到左括号
else if(item.equals(")")){
while(stack.size()!=0&&!stack.peek().equals("(")){
result.add(stack.pop());
}
//将左括号出栈
stack.pop();
}
//4.如果是运算符
else{
//如果当前符号优先级小于或者等于栈顶符号优先级,将栈顶符号出栈,并压入到中间符号栈中
while (stack.size()!=0&&getPriority(item)<=getPriority(stack.peek())){
result.add(stack.pop());
}
stack.push(item);
}
}
//6.将符号栈中元素全部压入到中间符号栈
while(stack.size()!=0){
result.add(stack.pop());
}
//7.返回result
return result;
}
/**
* 计算优先级
* */
public static int getPriority(String c) {
if (c.equals("*")|| c.equals("/")) {
return 1;
}else if(c.equals("+")||c.equals("-")){
return 0;
}else {
return -1;
}
}