常见算法<一>

来源:互联网 发布:unity3d 7.1安装教程 编辑:程序博客网 时间:2024/05/24 04:32

逆波兰表达式(Reverse Polish Notation)

1. 在算法中常说的后缀表达式,简单来说就是将正常的四则运算换一个写法

1+2 = 3  ->   12+ = 3

在习惯了这样的表达方式之后,我们将四则运算快速的转换成以下的表达方式,这里抄袭几个网上的例子:

["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9

["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6

利用栈的方式来处理这样的后缀表达式是非常方便的,他的原理也变得很简单易懂:

  • 从左至右依次读取
  • 遇到符号取出前两位的数字(利用栈的特性,先进先出)
  • 按照符号计算后,将结果再次压入栈内
  举个例子:["2", "1", "+", "3", "*"]  逐步分解:
  1. 模拟栈:从左至右读取放入栈,数据从栈顶输入即入口,从栈底被推出即出口。依次读入2,1两个数字放入栈
  2. 模拟栈:读取到符号【+】,不放入栈,连续从栈底取数,依次取出2位:2,1进行加法运算。得到的3再次压入栈内。到此为止,栈内只有3这一个数
  3. 模拟栈:继续读取列表,【+】号后面是数字3,放入栈内。目前栈内有两个3
  4. 模拟栈:继续读取列表,符号【*】,不放入栈,连续从栈底取数,依次取出2位:3,3进行乘法运算。得到的9再次压入栈内
  5. 模拟栈:继续读取列表,列表结束无结果,从栈底推出一位:9;此值即为答案

从这个例子来看,利用堆栈的特性能非常简单的用程序来完成这个四则运算。没有括号,不用作特殊判定,非常简便。但是还没有想好,怎么能非常方便的将中缀表达式转换成后缀表达式,或者这个思路本身就是错的?因该被运用在其他场景中。
下面献上计算后缀表达式的代码:其实理解思路后,代码已经不那么重要了(代码也是转自网上的哈)
public class Test { public static void main(String[] args) throws IOException {String[] tokens = new String[] { "2", "1", "+", "3", "*" };System.out.println(evalRPN(tokens));} public static 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());switch (t) {case "+":stack.push(String.valueOf(a + b));break;case "-":stack.push(String.valueOf(b - a));break;case "*":stack.push(String.valueOf(a * b));break;case "/":stack.push(String.valueOf(b / a));break;}}} returnValue = Integer.valueOf(stack.pop()); return returnValue;}}


0 0