看到p79,讲栈的一个应用——算术表达式求值,突然想起来这是来我现在这家公司面试的时候,被问的一道题。当年年少无知写计算器的时候,算术表达式求值用的是正则表达式的匹配(不涉及括号),面试给出的的答案也是这种办法。看到书里用栈来解决,真是牛逼。
DJ双栈算术表达式求值算法描述
这个算法是 E.W.Dijkstra大神发明,使用两个栈,一个用于保存运算符,一个用于保存操作数。(这个算法使用括号)
- 将操作数压入操作数栈
 
- 将运算符压入运算符栈
 
- 忽略左括号
 
- 遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算符结果压入操作数栈
 
在处理完最后一个右括号之后,操作数栈上只会有一个值,就是表达式的值。
java实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
   | public class Evaluate {   public static void main(String[] args) {     Stack<String> ops = new Stack<String>();     Stack<Double> vals = new Stack<Double>();     while (!StdIn.isEmpty()) {               String s = StdIn.readString();       if (s.equals("("));       else if (s.equals("+"))         ops.push(s);       else if (s.equals("-"))         ops.push(s);       else if (s.equals("*"))         ops.push(s);       else if (s.equals("/"))         ops.push(s);       else if (s.equals("sqrt"))         ops.push(s);       else if (s.equals(")")) {                  String op = ops.pop();         double v = vals.pop();         if(op.equals("+"))           v = vals.pop() + v;         else if (op.equals("-"))           v = vals.pop() - v;         else if (op.equals("*"))           v = vals.pop() * v;         else if (op.equals("/"))           v = vals.pop() / v;         else if (op.equals("sqrt")) v = Math.sqrt(v);           vals.push(v);       }        else vals.push(Double.parseDouble(s));     }     StdOut.println(vals.pop());   } }
  | 
 
它展示了一种重要的计算模型:将一个字符串解释为一段程序并执行该程序得到结果。
参考
     
    全文完。