Dijkstra双栈算术表达式求值算法

  1. import edu.princeton.cs.algs4.StdIn;
  2. import edu.princeton.cs.algs4.StdOut;
  3. public class Evaluate {
  4. public static void main(String[] args){
  5. ResizingArrayStack<String> ops = new ResizingArrayStack<>();
  6. ResizingArrayStack<Double> vals = new ResizingArrayStack<>();
  7. while (!StdIn.isEmpty()){
  8. String s = StdIn.readString();
  9. if(s.equals("("));
  10. else if(s.equals("+")) ops.push(s);
  11. else if(s.equals("-")) ops.push(s);
  12. else if(s.equals("*")) ops.push(s);
  13. else if(s.equals("/")) ops.push(s);
  14. else if(s.equals("sqrt")) ops.push(s);
  15. else if(s.equals(")")){
  16. String op = ops.pop();
  17. double val = vals.pop();
  18. if(op.equals("+")) val += vals.pop();
  19. else if(op.equals("-")) val -= vals.pop();
  20. else if(op.equals("*")) val *= vals.pop();
  21. else if(op.equals("/")) val = vals.pop() / val;
  22. else if(op.equals("sqrt")) val = Math.sqrt(val);
  23. vals.push(val);
  24. }
  25. else {
  26. vals.push(Double.parseDouble(s));
  27. }
  28. }
  29. StdOut.println(vals.pop());
  30. }
  31. }

要点

  1. 准备两个栈:运算符栈,操作数栈
  2. 忽略左括号,将操作数和运算符分别压入对应栈内
  3. 遇到右括号,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的结果压入操作数栈
  4. 方法局限性:最多只能有两个操作数在括号内运算且算式必须有左括号和右括号

注意事项
所有的字符间都要以空格隔开,在控制台下StdIn.isEmpty()需要接收ctrl+z才能结束输入,在idea中同理接收ctrl+d才能结束输入