/**
* 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