栈-逆波兰式求值问题
逆波兰式(后缀表达式):运算符总放在跟它相关的操作数之后。
而我们平常生活中使用的都是:中缀表达式。如:1+3*2
中缀表达式 | 逆波兰表达式 |
---|---|
a+b | ab+ |
a+(b-c) | abc-+ |
a+(b-c)*d | abc-d*+ |
a*(b-c)+d | abc-*d+ |
解决的问题:
给定一个只包含加减乘除四种运算的逆波兰表达式的数组表示方式,求出该逆波兰表达式的结果。
解决思路:
- 创建一个栈对象oprands存储操作数
- 从左往右遍历逆波兰表达式,得到每一个字符串
- 判断该字符串是不是运算符,如果不是,把该该操作数压入oprands栈中 "
- 如果是运算符,则从oprands栈中弹出两个操作数o1,o2
- 使用该运算符计算o1和o2,得到结果result
- 把该结果压入oprands栈中
- 遍历结束后,拿出栈中最终的结果返回
代码实现:
/**
* 逆波兰(后缀表达式)式求值
* 1、 创建一个栈对象oprands来存储操作数
* 2、 从左往右遍历逆波兰表达式,得到每一个字符
* 3、 判断字符是不是运算符,如果不是,把该操作数压入栈中
* 4、 如果是运算符,则从栈中弹出两个操作数o1、o2
* --这两个操作数就是与该运算符相匹配的两个数-结合栈的先进后出特点理解。
* 5、 使用该运算符计算o1、o2,得到结果再次压入栈中
* 6、 遍历结束中,把栈中最后的结果返回
*/
public class ReversePolishNotation {
public static void main(String[] args) {
//中缀表达式3*(17-15)+18/6 的逆波兰式如下
String[] notation = {"3","17","15","-","*","18","6","/","+"};
System.out.println(caculate(notation));
}
private static Integer caculate(String[] notation){
//1、 创建一个栈对象oprands来存储操作数
Stack<Integer> oprands = new Stack<>();
//2、 从左往右遍历逆波兰表达式,得到每一个字符
Integer o1;
Integer o2;
//如果是运算符,则从栈中弹出两个操作数o1、o2
for (String s : notation) {
//3、 判断字符是不是运算符,如果不是,把该操作数压入栈中
//重点理解运算时候谁在前谁在后。如是o1-o2 还是o2-o1
switch (s){
case "+" :
o1 = oprands.pop();
o2 = oprands.pop();
oprands.push(o2+o1);
break;
case "-" :
o1 = oprands.pop();
o2 = oprands.pop();
oprands.push(o2-o1);
break;
case "*" :
o1 = oprands.pop();
o2 = oprands.pop();
oprands.push(o2*o1);
break;
case "/" :
o1 = oprands.pop();
o2 = oprands.pop();
oprands.push(o2/o1);
break;
default:
oprands.push(Integer.parseInt(s));
break;
}
}
return oprands.pop();
}
}