关于计算数学表达式的方法有很多种,一般人们习惯是用中缀表达式去写,而计算机并不能很好理解与计算,计算起来也很麻烦,如何去写呢?

Calculator.java-CSDN下载 https://download.csdn.net/download/weixin_44688297/11897934

在这里我只会写我的算法以及思想,代码已经发出来。还有如何转化成后缀表达式,这里不会细说,有时间我再补。

先说一下为什么要用动态数组呢?为什么不用栈?因为我有一个对负号特殊的处理,动态数组的好处是我可以随便指定一个位置进行插入,方法很简单。

算法思想:利用动态数组实现栈。
1.先将表达式中的特殊的负号(将每一个左括号(前面的负号)转化成减号,再其前面加上一个0,因为这样就可以区分负号和减号。例如:18/48-(-(4+5))将这种类型转化成18/48-(0-(4+5))然后将其计算,因为我的算法里面不能对-(这种情况的负号进行区分,所以就想到了这种方法,为什么不写算法去区分呢?因为这种情况你根本无法预知会出现多少次,所以循环的判断语句无法写,我还不如直接对这种特殊的情况处理。
代码:

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
//这里的代码需要自己处理,后面我会将完整的代码全部发出,计算的也会发
ArrayList<Character>epress = new ArrayList<Character>();//对负号处理是动态数组
//18/48-(-(4+5))将这种类型转化成18/48-(0-(4+5))然后将其计算
for (int i = 0; i < expression.length(); i++) {
char a = expression.charAt(i);
epress.add(a);
}
boolean v = true;
int k = 0;
while (v){
if (epress.get(k) == '-' && k == 0){
if (epress.get(k + 1) == '(') {
epress.add(0, '0');
k += 3;//向后移动三位0(-,移动到下一个运算符
}else {
v = false;
}
}else if (epress.get(k) == '-' && epress.get(k-1) == '('){
epress.add(k,'0');
k += 3;//向后移动三位0(-,移动到下一个运算符
}else {
k++;
}
if (k == epress.size()){
v = false;
}
}
expression = "";//令表达式为空,然后依次将对负号处理完的动态epress里面的内容重新赋给表达式
for (int i = 0; i < epress.size(); i++) {
expression += epress.get(i);
}

中缀转化后缀表达式

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
	ArrayList operand = new ArrayList();//操作数动态数组
ArrayList<Character> operator = new ArrayList<Character>();//运算符动态数组
ArrayList<Character>epress = new ArrayList<Character>();//对负号处理是动态数组
//以下是计算表达式转化成后缀表达式
String expre = "";//存实数
for (int i = 0; i < expression.length(); i++) {
char a = expression.charAt(i);
if (a == '-') {
if (i > 0) {
if (expression.charAt(i-1) == '(') {//括号后面是负数的处理
expre += a;
}
else {
if (!"".equals(expre)) {//如果不为空
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
int length = operator.size();
if (length >= 1 ) {//-符号压栈与出栈
if (operator.get(length - 1) == '+' || operator.get(length - 1) == '-') {
operand.add(operator.get(length - 1));
operator.remove(length - 1);
}else if (operator.get(length - 1) == '*' || operator.get(length - 1) == '/'){
int size = operator.size();
while (size > 0) {//取栈
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
continue;
}
}
operator.add(a);
}
}else {
expre += a;
}
} else if ((a <= '9' && a >= '0') || a == '.') {
expre += expression.charAt(i);
if (i == expression.length() - 1) {//最后一个为数字
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
} else {
if (!expre.equals("")) {
double num = Double.valueOf(expre);
operand.add(num);
expre = "";
}
int size = operator.size();
if (size == 0 || a == '(') {//运算符栈为空
operator.add(a);
} else if (a != ')') {
if (operator.get(size - 1) == '(') {
operator.add(a);//压栈
} else if (operator.get(size - 1) == '*' || operator.get(size - 1) == '/') {
if (a == '+' ) {//取栈并压栈
while (size > operator.lastIndexOf('(') + 1) {
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
} else {
operand.add(operator.get(size - 1));
operator.remove(size - 1);
operator.add(a);
}
} else if (operator.get(size - 1) == '+' || operator.get(size - 1) == '-') {
if (a == '+' ) {//取栈并压栈
while (size > operator.lastIndexOf('(') + 1) {
if (operator.get(size - 1) != '(') {
operand.add(operator.get(size - 1));
}
operator.remove(size - 1);
size--;
}
operator.add(a);
} else {//压栈
operator.add(a);
}
}
} else {//取栈
while (size > operator.lastIndexOf('(') + 1) {
if (size - 1 >= 0) {
operand.add(operator.get(size - 1));
operator.remove(size - 1);
}
size--;
}
if (size > 0) {
operator.remove(size - 1);
} else if (size == 0) {
operator.remove(0);
}
}
}
}
//如果operator里面还有运算符,就将其弄到后缀表达式的最后
int size = operator.size();
while (size > 0){
operand.add(operator.get(size-1));
operator.remove(size-1);
size--;
}
System.out.println(operand);//输出已经转好的后缀表达式
}
2.将处理后的表达式转化成后缀表达式(逆波兰表达式)
用栈的思想以及动态数组,
3.计算后缀表达式(逆波兰表达式)
//找到最早出现的一个运算符,然后取其前面两个数字进行运算

//后缀表达式计算算法演示
**[-2.5, 3.2, -5.0, 4.0, +, , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2, -5+4, * , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2
(-5+4) , 3.0 /, -2.0, /, 9.0, , +]
[-2.5, 3.2
(-5+4), -2.0 /, 9.0, , +]
[-2.5, 3.2
(-5+4)/3.0/-2.0 , 9.0, , +]
[-2.5, 3.2
(-5+4)/3.0/-2.0
9.0, +]
*

如果大家需要更加多功能计算表达式的话,我后面还写了一个有三角函数,有ln,log,次方的,需要的话私聊我。。