本文介绍波兰式解析算法。
Leetcode 原题如下
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
中文翻译如下,有效的操作符包括: +, -, *,/。 每个操作数是一个整数或者是另个一表达式。
例子如上图。
Java实现如下,包括两个版本。
版本一,包括打印解析树,及"((2+1)*3)->".
import java.util.Stack;
public class Solution {
public static void main(String[] args){
String[] input1 = {"2", "1", "+", "3", "*"};
String[] input2 = {"4", "13", "5", "/", "+"};
Solution s = new Solution();
s.evalRPN(input1);
s.evalRPN(input2);
}
class Node{
int val;
String sVal;
Node(int val, String sval){
this.val = val;
this.sVal = sval;
}
}
private boolean isNumber(String str){
return str.matches("-?\\d+");
}
private boolean isOperator(String str){
return str.matches("[/+*-]");
}
private int compute(int left, int right, char operator){
switch(operator){
case '/': return left / right;
case '*': return left * right;
case '-': return left - right;
case '+': return left + right;
//case default return 0;//need to handle this one
}
return 0;
}
public int evalRPN(String[] tokens) {
Stack<Node> stack = new Stack();
for(int i = 0; i < tokens.length; i++){
String token = tokens[i];
if(isNumber(token)) {
int val = Integer.parseInt(token);
stack.push(new Node(val, token));
}else if(isOperator(token)){
Node right = stack.pop();
Node left = stack.pop();
int tmp = compute(left.val, right.val, token.charAt(0));
String stmp = "("+left.sVal + token + right.sVal+")";
Node rst = new Node(tmp, stmp);
stack.push(rst);
}
}
int rval = 0;
if(stack.size() == 1){
Node node = stack.pop();
System.out.println(node.sVal + "->" + node.val);
rval = node.val;
}
return rval;
}
}
输出结果如下:
((2+1)*3)->9
(4+(13/5))->6
版本二,简化版本,速度更快
public class Solution {
private boolean isNumber(String str){
return str.matches("-?\\d+");
}
private boolean isOperator(String str){
return str.matches("[/+*-]");
}
private int compute(int left, int right, char operator){
switch(operator){
case '/': return left / right;
case '*': return left * right;
case '-': return left - right;
case '+': return left + right;
//case default return 0;//need to handle this one
}
return 0;
}
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack();
for(int i = 0; i < tokens.length; i++){
String token = tokens[i];
if(isNumber(token)) {
int val = Integer.parseInt(token);
stack.push(val);
}else if(isOperator(token)){
int right = stack.pop();
int left = stack.pop();
int tmp = compute(left,right, token.charAt(0));
stack.push(tmp);
}
}
int rval = 0;
if(stack.size() == 1){
rval = stack.pop();
}
return rval;
}
}