04.1 使用栈完成计算功能

moye Lv6

4.1使用栈完成计算功能

思路分析:

  1. 通过一个index索引遍历表达式
  2. 发现数字,入数字栈
  3. 发现是符号:
    3.1 如果当前的符号栈为空,则直接入栈
    3.2 符号栈不为空,有操作符,则进行比较。当前操作符优先级小于等于栈中操作符,则需要从数栈中pop两个数,再从符号栈中pop一个符号,进行运算,并将结果入数字栈,然后将当前操作符入符号栈。
    3.3 3.2 符号栈不为空,有操作符,则进行比较。当前操作符优先级高于栈中操作符,则直接入符号栈
  4. 当表达式扫描完毕,就顺序从数栈、符号栈中pop相对应的符号,并运行,最后数栈中只有一个数字,即为最终的结果。

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package org.example;  

import java.util.Stack;

public class Calculator {
public static void main(String[] args) {
String expression = "70*2*2-5+3-4";
// Stack<Integer> numStack = new Stack<Integer>();
// Stack<Character> operStack = new Stack<Character>();

ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
int index = 0;//扫描索引
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' ';//将每次扫描得到的char保存在ch中
String keepNum = "";//拼接多位数
while (true) {
//依次得到expression的字符
ch = expression.substring(index, index + 1).charAt(0);
// 判断ch的值做相应的处理
if (operStack.isOper(ch)) {
if (!operStack.isEmpty()) {
//符号栈不为空,有操作符,则进行比较。
// 当前操作符优先级**小于等于**栈中操作符,则需要从数栈中pop两个数,
// 再从符号栈中pop一个符号,进行运算,并将结果入数字栈,
// 然后将当前操作符入符号栈。
if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);
operStack.push(ch);
} else {
// 当前操作符优先级**高于**栈中操作符,则直接入符号栈
operStack.push(ch);
}

} else {
operStack.push(ch);
}
} else {
// numStack.push(ch - 48);
// 1.当处理多位数时,不能立即入栈
// 2. 处理数时,需要想表达式的index再看一位,如果是数继续扫描,是符号才入栈
// 3. 定义字符串变量,用于拼接
keepNum += ch;

if (index == expression.length() - 1) {
numStack.push(Integer.parseInt(keepNum));
} else {
// 判断下一位字符是否为数字
if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
//
}
// index+1,判断是否扫描到最后
index++;
if (index >= expression.length()) {
break;
}
}

// 当表达式扫描完毕,就顺序从数栈、符号栈中pop相对应的符号,
// 并运行,最后数栈中只有一个数字,即为最终的结果。
while (true) {
// 符号栈为空,则数栈中只有一个数,最后的结果
if (operStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);
}
System.out.printf("表达式是%s = %s\n", expression, numStack.peek());
}
}

class ArrayStack2 {
private int maxSize;
private int[] stack;
private int top = -1;

// 构造器
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[this.maxSize];
}

public boolean isFull() {
return top == (maxSize - 1);
}

public boolean isEmpty() {
return top == -1;
}

public void push(int value) {
if (isFull()) {
System.out.println("栈满");
return;
}
top++;
stack[top] = value;
}

public int pop() {
if (isEmpty()) {
// System.out.println("栈空");
throw new RuntimeException("栈空");
}
int value = stack[top];
top--;
return value;
}

// 遍历时需从栈顶开始显示数据
public void list() {
if (isEmpty()) {
System.out.println("栈空");
return;
}
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d]=%d\n", i, stack[i]);
}
}

//返回运算符的优先级
public int priority(int oper) {
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '+' || oper == '-') {
return 0;
} else {
return -1;
}
}

public boolean isOper(char val) {
return val == '+' || val == '-' || val == '*' || val == '/';
}

public int cal(int num1, int num2, int oper) {
int res = 0;
switch (oper) {
case '+':
res = num1 + num2;
break;
case '*':
res = num1 * num2;
break;
case '-':
res = num2 - num1;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}

public int peek() {
return stack[top];
}
}
  • 标题: 04.1 使用栈完成计算功能
  • 作者: moye
  • 创建于 : 2024-07-18 14:32:54
  • 更新于 : 2025-12-11 14:39:48
  • 链接: https://www.kanes.top/2024/07/18/04.1 使用栈完成计算功能/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
04.1 使用栈完成计算功能