/**
 * 1.先转换为逆波兰顺序
 *      数字直接存入list,符号压入栈中,但是如果栈底元素不大于该运算符的运算顺序,则将栈底pop,直到大于栈底运算符为止,再压入栈中,
 *      最后将运算符依次全部pop(以上pop出的运算符存入list)
 * 2.根据逆序算出结果
 *      从头到尾依次读取list的数据,将数字压入栈中,出现运算符后pop出两个数字进行运算,运算式为"后pop数 运算符 先pop数"
 *      运算完毕将结果再次压入栈中.结束后,将数字栈中的唯一一个数字pop出并将其返回.
 *
 *
 * 学习之处:
 *  1.String对象的比较不要用==,>,<.而是用equal()函数.
 *  2.使用HashMap<Object,Integer>()的定义可以给对象进行编号或加权.
 *  3.需要时要给读取的信息加上结尾标志,如读入String结尾的"#".
 *  4.取String的单个字母:String temps=String.valueOf(expression.charAt(i));
 *  5.检测数字:temps.matches("[0-9.]")
 **/
1 public class Calculator {
  2     private String string;
  3     private MyStack<String> opratorStack = new MyStack();
  4     private MyStack<Double> numberStack = new MyStack();
  5     private ArrayList<String> rpnList = new ArrayList();
  6     private Map<String,Integer> priorityMap=new HashMap<String,Integer>();//用于存储操作符优先级的Map
  7     //初始化优先级约定(可根据计算的复杂程度扩展)
  8 
  9     public Calculator(String str)
 10     {
 11         priorityMap.put("+",0);
 12         priorityMap.put("-",0);
 13         priorityMap.put("*", 1);
 14         priorityMap.put("/", 1);
 15         priorityMap.put("(", 2);
 16         string = str+"#";
 17     }
 18     private int getPriority(String op)//得到一个操作符的优先级
 19     {
 20         return priorityMap.get(op);
 21     }
 22 
 23     private void toRpn() {
 24 
 25         String temp = "";
 26         for (int i = 0; i < string.length(); i++) {
 27             String ch = String.valueOf(string.charAt(i));
 28             if (ch.matches("[0-9.]"))
 29                 temp += ch;
 30 
 31             else { //如果操作数完整,现将其存入list中再进行后续操作
 32 
 33                 if(!temp.equals("")) {//防止加入进空格
 34                     rpnList.add(temp);
 35                     temp = "";
 36                 }
 37 
 38                 if (ch.equals("#")) { //读取结束时将运算符栈依次pop并添加到rpnList中
 39                     while (!opratorStack.isEmpty()) {
 40                         rpnList.add(opratorStack.pop());
 41                     }
 42                 } else if (ch.equals(")")) { //遇到右括号将左括号后的运算符全部pop
 43                     String op = opratorStack.pop();
 44                     while (!op .equals("(")) {
 45                         rpnList.add(op);
 46                         op = opratorStack.pop();
 47                     }
 48                 } else {
 49                     if (!opratorStack.isEmpty()) { //如果为普通的运算符
 50                         String endOprator = opratorStack.endValue();
 51 
 52                         while (!endOprator.equals( "(") && (getPriority(ch) < getPriority(endOprator)
 53                                 || getPriority(ch) == getPriority(endOprator))) {
 54                             rpnList.add(opratorStack.pop());//如果
 55                             if (!opratorStack.isEmpty()) {
 56                                 endOprator = opratorStack.endValue();
 57                             }else
 58                                 break;
 59 
 60                         }
 61 
 62                         opratorStack.push(ch);
 63                     }
 64                     else
 65                         opratorStack.push(ch);
 66                 }
 67             }
 68         }
 69     }
 70 
 71     public double calculate(String string){
 72         this.string = string+"#";
 73         return calculate();
 74     }
 75 
 76     public double calculate(){
 77         toRpn();//逆波兰序列转换
 78 
 79         //扫描String对象
 80         for(int i = 0; i < rpnList.size(); i++){
 81             String temp = rpnList.get(i);
 82             //匹配第一个字符,为数字的则将String对象转为Double并存入numberStack中
 83             if(String.valueOf(temp.charAt(0)).matches("[0-9]")){
 84                 numberStack.push(Double.valueOf(temp));
 85             } //匹配到运算符,调出最后两个numberStack中数字进行运算,并将得数压入栈中(栈次底数 操作符 栈最底数)
 86             else {
 87                 //Double n = opration(numberStack.pop(), numberStack.pop(), temp);
 88                 Double n = numberStack.pop();
 89                 numberStack.push(opration(numberStack.pop(), n , temp));
 90             }
 91         }
 92 
 93         rpnList = new ArrayList();//为下次运算做准备
 94         return numberStack.pop();
 95     }
 96 
 97     private Double opration(Double val1,Double val2,String oprator){
 98         if(oprator.equals("+"))
 99             val1 += val2;
100         else if(oprator.equals("-"))
101             val1 -= val2;
102         else if(oprator.equals("*"))
103             val1 *= val2;
104         else
105             val1 /= val2;
106         return val1;
107     }
108 
109     public static void main(String[] args) {
110         String string1 = "12+2*37-(4*5+6)*7";
111         Calculator calculator = new Calculator(string1);
112 
113         System.out.println(calculator.calculate());
114         System.out.println(calculator.calculate("4.99+5.99+6.99*1.06"));
115     }
116 }

运算结果:

-96.0
18.389400000000002

Process finished with exit code 0