表达式一般由操作数(Operand)、运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间,
这称为中缀表达式(Infix Expression),如A+B。
波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式:
把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB;
把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+;
其中,逆波兰表达式在编译技术中有着普遍的应用。
算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
二、逆波兰表达式求值算法:
1、循环扫描语法单元的项目。
2、如果扫描的项目是操作数,则将其压入操作数堆栈,并扫描下一个项目。
3、如果扫描的项目是一个二元运算符,则对栈的顶上两个操作数执行该运算。
4、如果扫描的项目是一个一元运算符,则对栈的最顶上操作数执行该运算。
5、将运算结果重新压入堆栈。
6、重复步骤2-5,堆栈中即为结果值。
public class Solution { public int evalRPN(String[] tokens) { int returnValue = 0; String operators = "+-*/"; Stack<String> stack = new Stack<String>(); for(String t : tokens){ if(!operators.contains(t)){ stack.push(t); }else{ int a = Integer.valueOf(stack.pop()); int b = Integer.valueOf(stack.pop()); int index = operators.indexOf(t); switch(index){ case 0: stack.push(String.valueOf(a+b)); break; case 1: stack.push(String.valueOf(b-a)); break; case 2: stack.push(String.valueOf(a*b)); break; case 3: stack.push(String.valueOf(b/a)); break; } } } returnValue = Integer.valueOf(stack.pop()); return returnValue; } }
参考
http://www.programcreek.com/2012/12/leetcode-evaluate-reverse-polish-notation/
http://blog.csdn.net/geniusluzh/article/details/8192780
http://www.cnblogs.com/wanghetao/archive/2012/04/23/2466580.html