目录
一、原题再现
二、问题分析
三、完整代码
一、原题再现
150. 逆波兰表达式求值
有效的算符包括
+
、-
、*
、/
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。注意 两个整数之间的除法只保留整数部分。
可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入:tokens = ["2","1","+","3","*"] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9示例 2:
输入:tokens = ["4","13","5","/","+"] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6示例 3:
输入:tokens = ["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 <= tokens.length <= 104
tokens[i]
是一个算符("+"
、"-"
、"*"
或"/"
),或是在范围[-200, 200]
内的一个整数逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
- 平常使用的算式则是一种中缀表达式,如
( 1 + 2 ) * ( 3 + 4 )
。- 该算式的逆波兰表达式写法为
( ( 1 2 + ) ( 3 4 + ) * )
。逆波兰表达式主要有以下两个优点:
- 去掉括号后表达式无歧义,上式即便写成
1 2 + 3 4 + *
也可以依据次序计算出正确结果。- 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中
二、问题分析
遍历数组,将数字压入栈中,当遇见运算符时,就从栈中取出两个元素进行运算,并将结果压入栈中。直到遍历完最后一次运算结果压入栈中。
本题有一个注意点,就是将String类型转换成long类型才能进行加减乘除的运算。
1.Long.parseLong(String):将 string 参数解析为有符号十进制 long,字符串中的字符必须都是十进制数字。
2.Long.valueOf(String):参数String表示,指定 String 的值的 Long 对象。该参数被解释为表示一个有符号的十进制 long,该值与用该参数作为参数的 parseLong(java.lang.String) 方法得到的值非常相似。只是最后被转换为一个Long的包装类。
三、完整代码
class Solution { public int evalRPN(String[] tokens) { Stack <Long> stack= new Stack<>(); for(int i=0;i<tokens.length;i++){ if(!isOperator(tokens[i])){ long elem=Long.parseLong(tokens[i]); stack.push(elem); }else{ long elem2=stack.pop(); long elem1=stack.pop(); long result=calculate(elem1,elem2,tokens[i]); stack.push(result); } } Long e=stack.peek(); long ans=e.longValue(); return (int)ans; } private boolean isOperator(String token){ if((token.equals("+"))||(token.equals("*"))||(token.equals("-"))||(token.equals("/"))){ return true; }else{ return false; } } private long calculate(long elem1,long elem2,String token){ switch(token){ case "+":return elem1+elem2; case "-":return elem1-elem2; case "*":return elem1*elem2; case "/":return elem1/elem2; default:return -1; } } }