一、引子
首先我们来看一个式子:
(a+b)*c-d,这种常见的式子也就是我们的中缀表达式。
那什么是后缀表达式呢?后缀表达式又该如何转换?示例如下:
我们根据计算顺序,对上面的式子逐层加括号
然后把每层括号内的符号移动到对应层外:
最后把扩号去掉:
这样得到的式子ab+c*d-就是我们需要的后缀表达式
那么聪明如你,很快就会知道中缀表达式转前缀表达式的方法,对标转后缀,也就是把符号提到括号前面即可。
二、后缀表达式求值
我们仍以上面得到的后缀表达式ab+c* d-为例:
我们创建一个栈,和一个变量i:
用变量i去遍历后缀表达式ab+c*d-:
i对应的数据为操作数a,将a放入栈中,i++
继续用i遍历表达式:
i对应的数据为操作数b,将b放入栈中,i++
继续用i遍历表达式:
i对应的数据为操作符+,取栈顶元素放操作符右边,再取栈顶元素放操作符左边(这里左右顺序不可改,我们这里是加法好像没有区别,但如果是减法,a-b和b-a完全是两个概念)
得到a+b的值x后,把x放入栈中,i++
继续用i遍历表达式:
i对应的数据为操作数c,将c放入栈中,i++
继续用i遍历表达式:
i对应的数据为操作符 *,取栈顶元素放操作符右边,再取栈顶元素放操作符左边
得到x *c的值y后,将y放入栈中,i++:
继续用i遍历表达式:
i对应的数据为操作数d,将d放入栈中,i++
继续用i遍历表达式:
i对应的数据为操作符 -,取栈顶元素放操作符右边,再取栈顶元素放操作符左边
最后将z放入栈中,i继续往后走,发现没有可遍历的了,就把最终结果z拿出来即可。我们这里可以简单验证一下上面的方法对不对:
假定a,b,c,d值分别为1,2,3,4。用上面的方法求出的z是5
而正常的中缀表达式(a+b)*c-d也就是(1+2) * 3-4=5
三、力扣例题实战
代码示例如下:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack=new Stack<>();
for(int i=0;i<tokens.length;i++){
String val=tokens[i];
if(!isOperation(val)){
//不是运算符(是运算数据)
stack.push(Integer.parseInt(val));
//这里不能直接放,因为我们直接放的话是字符串,但栈里存放的是整形
}else{
//是运算符
//判断是什么运算符
int num2=stack.pop();
int num1=stack.pop();
switch(val){
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1/num2);
break;
}
}
}
return stack.pop();
}
private boolean isOperation(String x){
if(x.equals("+")||x.equals("-")||x.equals("*")||x.equals("/")){
return true;
}else{
return false;
}
}
}