题目:
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +
, -
, *
, /
. Each operand may be an integer or another expression.
Some examples:
["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
题目中并没有考虑 invalid Polish Notation 的处理,还有 Integer Overflow、Devide by 0.
Polish Notation(wiki) 的优点:
所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级.
try/catch as conditional:
这里使用 helper 容易扩展更多的运算。但是,这里使用 try/catch 来实现,是非常不恰当的。原因如下:
You really should not use try
/catch
and if
interchangeably.
try
/catch
is for things that go wrong that are outside of your control and not in the normal program flow. For example, trying to write to a file and the file system is full? That situation should typically be handled with try
/catch
.
if
statements should be normal flow and ordinary error checking. So, for example, user fails to populate a required input field? Use if
for that, not try
/catch
.
There is more overhead even if the exception is never thrown.
Solution with try/catch:
1 public class Solution { 2 public int evalRPN(String[] tokens) { 3 if(tokens == null || tokens.length == 0) { 4 return 0; 5 } 6 7 Stack<Integer> stack = new Stack<>(); 8 9 for(String str: tokens) { 10 try { 11 int num = Integer.parseInt(str); 12 stack.push(num); 13 } catch (Exception e){ 14 int num2 = stack.pop(); 15 int num1 = stack.pop(); 16 int num = helper(num1, num2, str); 17 stack.push(num); 18 } 19 } 20 21 return stack.pop(); 22 } 23 24 private int helper(int num1, int num2, String str) { 25 int res = 0; 26 27 switch(str) { 28 case "*": 29 res = num1 * num2; 30 break; 31 case "/": 32 res = (num2 == 0) ? 0: num1 / num2; 33 break; 34 case "+": 35 res = num1 + num2; 36 break; 37 case "-": 38 res = num1 - num2; 39 } 40 return res; 41 } 42 }
Solution without try/catch:
public class Solution { public int evalRPN(String[] tokens) { if(tokens == null || tokens.length == 0) { return 0; } Stack<Integer> stack = new Stack<>(); for(String str: tokens) { switch(str) { case "*": stack.push(stack.pop() * stack.pop()); break; case "+": stack.push(stack.pop() + stack.pop()); break; case "-": stack.push(-stack.pop() + stack.pop()); break; case "/": int num1 = stack.pop(); int num2 = stack.pop(); int num = (num1 == 0)?0:num2/num1; stack.push(num); break; default: stack.push(Integer.parseInt(str)); } } return stack.pop(); } }