题目:根据 逆波兰表示法,求表达式的值。
有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
- 整数除法只保留整数部分。
- 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: [“2”, “1”, “+”, “3”, “*”]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入: [“4”, “13”, “5”, “/”, “+”]
输出: 6
解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入: [“10”, “6”, “9”, “3”, “+”, “-11”, “", “/”, "”, “17”, “+”, “5”, “+”]
输出: 22
解释:
该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面
- 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )
- 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:
- 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
- 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
题解思路:遇到数字则入栈,遇到算数符号则出栈,这里字符串比较用.equals()。以及string转integer用Integer.tovalueOf 或者转int的话用Integer.parseInt().
package com.lcz.leetcode;
import java.util.*;
/**
* 逆波兰表达式求值
* 逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
* 逆波兰表达式:
* - 去掉括号后表达式无歧义
* - 适合用栈操作运算,遇到数字则入栈,遇到运算符则取出栈顶两个数字进行计算。
* @author LvChaoZhang
*
*/
public class Leetcode150 {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
HashSet<String> set = new HashSet<>();
set.add("+");
set.add("-");
set.add("*");
set.add("/");
for(int i=0;i<tokens.length;i++) {
String s = tokens[i];
if(set.contains(s)) {
int second = stack.pop();
int first = stack.pop();
if(s.equals("+")) {
stack.push(first+second);
}else if(s.equals("-")) {
stack.push(first-second);
}else if(s.equals("*")) {
stack.push(first*second);
}else if(s.equals("/")) {
stack.push(first/second);
}
}else {
stack.push(Integer.valueOf(s));
}
}
return stack.pop();
}
}
public int evalRPN2(String[] tokens) {
Stack<String> stack = new Stack<>();
HashSet<String> hashSet = new HashSet<>();
hashSet.add("+");
hashSet.add("-");
hashSet.add("*");
hashSet.add("/");
for(String str:tokens) {
if(isOperation(hashSet, str)) {
// 运算符
int second = stringToNumber(stack.pop());
int first = stringToNumber(stack.pop());
stack.push(eval(first,second,str.charAt(0)) + "");
}else {
// 非运算符
stack.push(str);
}
}
return stringToNumber(stack.pop());
}
private static int eval(int a,int b,char op) {
switch(op) {
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
}
return 0;
}
private static int stringToNumber(String s) {
int sign = 1;
int start = 0;
if(s.charAt(0)=='-') {
sign = -1;
start = 1;
}
int res = 0;
for(int i=start;i<s.length();i++) {
res = res*10 + s.charAt(i)-'0';
}
return res*sign;
}
public boolean isOperation(HashSet<String> hashSet,String s) {
return hashSet.contains(s);
}