1. 后缀表达式求值
- 后缀表达式也叫逆波兰表达式,其求值过程可以用到栈来辅助存储。假定待求值的后缀表达式为:6 5 2 3 + 8 * + 3 + *,则其求值过程如下:
- 遍历表达式,遇到的数字首先放入栈中,此时栈如下所示:
- 接着读到“+”,则弹出3和2,执行3+2,计算结果等于5,并将5压入到栈中。
- 读到8,将其直接放入栈中。
- 读到“”,弹出8和5,执行85,并将结果40压入栈中。而后过程类似,读到“+”,将40和5弹出,将40+5的结果45压入栈…以此类推。最后求的值288。
2. 中缀表达式转后缀表达式
规则很多,还是用实例比较容易说清楚整个过程。以上面的转换为例,输入为a + b * c + (d * e + f)*g,处理过程如下:
1)首先读到a,直接输出。
2)读到“+”,将其放入到栈中。
3)读到b,直接输出。
4)读到“*”,因为栈顶元素"+“优先级比” * " 低,所以将" * "直接压入栈中。
5)读到c,直接输出。
6)读到" + “,因为栈顶元素” * “的优先级比它高,所以弹出” * “并输出, 同理,栈中下一个元素” + “优先级与读到的操作符” + “一样,所以也要弹出并输出。然后再将读到的” + "压入栈中。
7)下一个读到的为"(",它优先级最高,所以直接放入到栈中。
8)读到d,将其直接输出。
9)读到" * “,由于只有遇到” ) “的时候左括号”(“才会弹出,所以” * "直接压入栈中。
10)读到e,直接输出。
11)读到" + “,弹出” * “并输出,然后将”+"压入栈中。
12)读到f,直接输出。
13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"(“为止。这里右括号前只有一个操作符”+"被弹出并输出。
14)读到" * ",压入栈中。读到g,直接输出。
15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。
3. 后缀表达式(逆波兰表达式)求值
这就是一个栈的思想,我们贴上代码
class Solution {
public int evalRPN(String[] tokens) {
Stack<String> stack = new Stack<>();
for(String token:tokens){
if(token.length() == 1 && (token.charAt(0) == '+' || token.charAt(0) == '-' || token.charAt(0) == '*' || token.charAt(0) == '/')){
switch(token.charAt(0)){
case '+':{
int a = getNum(stack.pop());
int b = getNum(stack.pop());
stack.add(String.valueOf(a + b));
break;
}
case '-':{
int a = getNum(stack.pop());
int b = getNum(stack.pop());
stack.add(String.valueOf(b - a));
break;
}
case '*':{
int a = getNum(stack.pop());
int b = getNum(stack.pop());
stack.add(String.valueOf(a * b));
break;
}
case '/':{
int a = getNum(stack.pop());
int b = getNum(stack.pop());
stack.add(String.valueOf(b/a));
break;
}
}
}else{
stack.add(token);
}
}
return getNum(stack.pop());
}
public int getNum(String s){
char c[] = s.toCharArray();
int i = 0;
if(c[0] == '-') i = 1;
int res = 0;
for(;i < c.length;i++){
res=res*10 + c[i] - 48;
}
if(c[0] == '-') res = -res;
return res;
}
}