Java 进行四则运算

更加便捷的进行四则运算,且代码足够简单。
一般的逻辑是按照正常人的思路来解析,这样难度太大。
转换思路和原理,可以参考将中缀表达式转化为后缀表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.piggsoft;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

public class Arithmetic {
//操作符stack
private Stack<String> operator = new Stack<String>();
//后缀表达式
private List<String> postFix = new ArrayList<String>();

private Pattern operatorPattern = Pattern.compile("[\\d\\.]");
private Pattern arithmeticPattern = Pattern.compile("[\\(\\)\\+\\-/\\*]");

//将中缀表达式换为后缀表达式
public void parse(String s) {
s = replace(s);
int j = 0;
for (int i = 0; i < s.length(); i++) {
String temp = s.substring(i, i + 1);
if (operatorPattern.matcher(temp).matches()) {
continue;
}
if (arithmeticPattern.matcher(temp).matches()) {
j = process(j, i, s, temp);
} else if ("".equals(temp)) {
return;
}
}
if (j < s.length()) {
postFix.add(s.substring(j, s.length()));
}
while (!this.operator.isEmpty()) {
postFix.add(operator.pop());
}
}

private String replace(String s) {
return s.replaceAll("\\s", "");
}

private int process(int startIndex, int currentIndex, String str, String word) {
if (startIndex != currentIndex) {
postFix.add(str.substring(startIndex, currentIndex));
}
addOperator(word);
startIndex = currentIndex + 1;
if (startIndex > str.length()) {
startIndex = str.length();
}
return startIndex;
}

public void addOperator(String operator) {
if ("(".equals(operator)) {

} else if (")".equals(operator)) {
while (!this.operator.isEmpty()) {
String temp = this.operator.pop();
if ("(".equals(temp)) {
break;
} else {
postFix.add(temp);
}

}
return;
} else if (!this.operator.isEmpty()) {
while (!this.operator.isEmpty()) {
String temp = this.operator.peek();
if (needPop(temp, operator)) {
this.postFix.add(this.operator.pop());
} else {
break;
}
}
}
this.operator.add(operator);
}

public boolean needPop(String inStackTop, String current) {
return getLevel(current.charAt(0)) <= getLevel(inStackTop.charAt(0));
}

public int getLevel(char operator) {
switch (operator) {
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
default:
return -1;
}
}

public BigDecimal compute() {
Stack<BigDecimal> stack = new Stack<BigDecimal>();
for (int i = 0; i < this.postFix.size(); i++) {
if (arithmeticPattern.matcher(postFix.get(i)).matches()) {
BigDecimal bd2 = stack.pop();
BigDecimal bd1 = stack.pop();
BigDecimal temp = compute(postFix.get(i).charAt(0), bd1, bd2);
stack.add(temp);
} else {
stack.add(new BigDecimal(postFix.get(i)));
}
}
return stack.pop();
}

private BigDecimal compute(char operator, BigDecimal bd1, BigDecimal bd2) {
switch (operator) {
case '+':
return bd1.add(bd2);
case '-':
return bd1.subtract(bd2);
case '*':
return bd1.multiply(bd2);
case '/':
return bd1.divide(bd2);//应当使用bd1.divide(divisor, scale, roundingMode);
default:
return null;
}
}

public static void main(String[] args) {
Arithmetic arithmetic = new Arithmetic();
arithmetic.parse("9 + (3 - 1) * 3 + 10 / 2");
System.out.println(arithmetic.postFix);
System.out.println(arithmetic.compute());

arithmetic = new Arithmetic();
arithmetic.parse("9 + (3 - 1) * 3 + 10 / 2 + 1000 - 200 - (100 + 5 - 9 / 3)");
System.out.println(arithmetic.postFix);
System.out.println(arithmetic.compute());

arithmetic = new Arithmetic();
arithmetic.parse("9 + (3 - 1) * 3 + 10 / 2 + 1000 - 200 - (100 + 5 - 9 / 3)");
System.out.println(arithmetic.postFix);
System.out.println(arithmetic.compute());
}
}