一、什么是逆波兰表达式?
逆波兰表达式又叫做后缀表达式。逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasiewicz)于1929年首先提出的一种表达式的表示方法 。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。(摘自百度百科)
我们再来看看什么是中缀表达式…其实。中缀表达式就是我们平时书写的数学表达式。比如:
2 + 3 * 5
( 2 + 3 ) * 5
我们再来看看上面两个中缀表达式对应的后缀表达式
2 3 5 * +
2 3 5 + *
说实话,后缀表达式我要是没学过我指定不知道啥意思,中缀表达式那么明了,为啥还用后缀表达式?
我们人能够识别括号,能够知道先乘除后加减,但是,计算机不能啊!!!所以引入了后缀表达式。
问题又来了,计算机怎么根据后缀表达式计算结果呢?这是一个关于栈的故事了。
1. 只要是数字,我们就放入栈中。
2. 遇到运算符(+ - * /)后,取出栈顶两个元素进行计算。然后再将结果放入栈中。
- 继续上述操作,直到后缀表达式遍历完成,然后就得到了结果。
注意:遇到运算符后取出的第一个操作数一定当做右操作数,不然结果有时候会出问题。比如栈顶元素依次是25、5,本来结果是 25 / 5 结果你把5当做左操作数,用 5 / 25,那么就得不偿失了。
二、中缀表达式转后缀表达式
现在肖肖有个中缀表达式 a + b *(c+d)- e * f,需要你帮忙转成后缀表达式。但是他比较懒,需要你帮忙,来把baby。
规则是这样的,先乘除后加减,按照这样的顺序给操作数加上括号,全部完成后,将运算符移到对应的括号外。
三、代码实现后缀表达式的计算
根据逆波兰表达式的原理。我们使用辅助栈来计算。(当然,使用List也是可以滴)
LeetCode链接:150.逆波兰表达式求值
public int evalRPN(String[] tokens) {
Stack<Integer> res = new Stack<>();
//遍历字符串数组
for (int i = 0;i < tokens.length;i++) {
//条件分支选择
if (tokens[i].equals("+")) {
//取出栈顶两个元素
int nums1 = Integer.valueOf(res.pop());
int nums2 = Integer.valueOf(res.pop());
int sum = nums2+nums1;
res.push(sum);
}else if (tokens[i].equals("-")) {
int nums1 = Integer.valueOf(res.pop());
int nums2 = Integer.valueOf(res.pop());
int sub = nums2-nums1;
res.push(sub);
}else if (tokens[i].equals("*")) {
int nums1 = Integer.valueOf(res.pop());
int nums2 = Integer.valueOf(res.pop());;
int fac = nums2*nums1;
res.push(fac);
}else if (tokens[i].equals("/")) {
int nums1 = Integer.valueOf(res.pop());
int nums2 = Integer.valueOf(res.pop());
int div = nums2/nums1;
res.push(div);
}else {
res.push(Integer.valueOf(tokens[i]));
}
}
return res.pop();
}
冲啊兄弟们!