算法Sedgewick第四版-第1章基础-020一按优先级计算表达式的值

 

  1 /******************************************************************************
  2  *  Compilation:  javac EvaluateDeluxe.java
  3  *  Execution:    java EvaluateDeluxe
  4  *  Dependencies: Stack.java
  5  *
  6  *  Evaluates arithmetic expressions using Dijkstra's two-stack algorithm.
  7  *  Handles the following binary operators: +, -, *, / and parentheses.
  8  *
  9  *  % echo "3 + 5 * 6 - 7 * ( 8 + 5 )" | java EvaluateDeluxe
 10  *  -58.0
 11  *
 12  *
 13  *  Limitiations
 14  *  --------------
 15  *    -  can easily add additional operators and precedence orders, but they
 16  *       must be left associative (exponentiation is right associative)
 17  *    -  assumes whitespace between operators (including parentheses)
 18  *
 19  *  Remarks
 20  *  --------------
 21  *    -  can eliminate second phase if we enclose input expression
 22  *       in parentheses (and, then, could also remove the test
 23  *       for whether the operator stack is empty in the inner while loop)
 24  *    -  see http://introcs.cs.princeton.edu/java/11precedence/ for
 25  *       operator precedence in Java
 26  *
 27  ******************************************************************************/
 28 
 29 import java.util.TreeMap;
 30 
 31 public class EvaluateDeluxe {
 32 
 33     // result of applying binary operator op to two operands val1 and val2
 34     public static double eval(String op, double val1, double val2) {
 35         if (op.equals("+")) return val1 + val2;
 36         if (op.equals("-")) return val1 - val2;
 37         if (op.equals("/")) return val1 / val2;
 38         if (op.equals("*")) return val1 * val2;
 39         throw new RuntimeException("Invalid operator");
 40     }
 41 
 42     public static void main(String[] args) {
 43 
 44         // precedence order of operators
 45         TreeMap<String, Integer> precedence = new TreeMap<String, Integer>();
 46         precedence.put("(", 0);   // for convenience with algorithm
 47         precedence.put(")", 0);  
 48         precedence.put("+", 1);   // + and - have lower precedence than * and /
 49         precedence.put("-", 1);
 50         precedence.put("*", 2);
 51         precedence.put("/", 2);
 52 
 53         Stack<String> ops  = new Stack<String>();
 54         Stack<Double> vals = new Stack<Double>();
 55 
 56         while (!StdIn.isEmpty()) {
 57 
 58             // read in next token (operator or value)
 59             String s = StdIn.readString();
 60 
 61             // token is a value
 62             if (!precedence.containsKey(s)) {
 63                 vals.push(Double.parseDouble(s));
 64                 continue;
 65             }
 66 
 67             // token is an operator
 68             while (true) {
 69 
 70                 // the last condition ensures that the operator with higher precedence is evaluated first
 71                 if (ops.isEmpty() || s.equals("(") || (precedence.get(s) > precedence.get(ops.peek()))) {
 72                     ops.push(s);
 73                     break;
 74                 }
 75 
 76                 // evaluate expression
 77                 String op = ops.pop();
 78 
 79                 // but ignore left parentheses
 80                 if (op.equals("(")) {
 81                     assert s.equals(")");
 82                     break;
 83                 }
 84 
 85                 // evaluate operator and two operands and push result onto value stack
 86                 else {
 87                     double val2 = vals.pop();
 88                     double val1 = vals.pop();
 89                     vals.push(eval(op, val1, val2));
 90                 }
 91             }
 92         }
 93 
 94         // finished parsing string - evaluate operator and operands remaining on two stacks
 95         while (!ops.isEmpty()) {
 96             String op = ops.pop();
 97             double val2 = vals.pop();
 98             double val1 = vals.pop();
 99             vals.push(eval(op, val1, val2));
100         }
101 
102         // last value on stack is value of expression
103         StdOut.println(vals.pop());
104         assert vals.isEmpty();
105         assert ops.isEmpty();
106     }
107 }

 

posted @ 2016-04-20 10:39  shamgod  阅读(238)  评论(0编辑  收藏  举报
haha