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