今天跟着尚硅谷的韩老师做了一个中缀表达式计算机案例
package cn.wangmengqi.stack;
public class Calculator {
public static void main(String[] args) {
String expression = "70+2*6";//要计算的表达式
int index = 0;//保存表达式下标
int num1;//保存第一个出数栈的数
int num2;//保存第二个出数栈的数
int oper;//保存出符号栈的元素
int res;//保存每一次计算后的结果
String teepch = "";//保存多位数字的临时字符串
ArrayStack2 numStack = new ArrayStack2(10);//创建数栈
ArrayStack2 operStack = new ArrayStack2(10);//创建符号栈
while (true) {
char ch = expression.charAt(index);//保存每一次扫描到的符号
if (operStack.isOper(ch)) {// 是一个符号
// 先判断栈是否为空
if (!operStack.isEmpty()) {// 符号栈里面有数据
// 判断符号优先级
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 {
// 再扫描一个数字之后,不能直接入栈,而是查看一下后一个字符是不是数字
teepch += ch;
// 判断当前数字是否为最后一个字符
if (index == expression.length() - 1) {
//这一步是为了防止当扫描到最后那个数据是后出现下表异常
numStack.push(Integer.parseInt(teepch));
} else {// 不为最后一个字符
if (operStack.isOper(expression.charAt(index + 1))) {
// 如果后一位是运算符,则入栈 keepNum = "1" 或者 "123"
numStack.push(Integer.parseInt(teepch));
// 将字符串清空
teepch = "";
}
}
}
index++;//每一次扫描后,将下标加1
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.println(numStack.pop());//将最后的结果打印出来
}
}
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 int peek() {
return stack[top];
}
// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
// 判断栈是否为满
public boolean isPull() {
return top == maxSize - 1;
}
// 进栈
public void push(int value) {
// 判断栈是否为满
if (isPull()) {
System.out.println("栈满,无法加入");
return;
}
top++;
stack[top] = value;
}
// 出栈
public int pop() {
if (isEmpty()) {
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(int oper) {
if (oper == '*' || oper == '/' || oper == '-' || oper == '+') {
return true;
} else {
return false;
}
}
// 进行运算方法
public int cal(int num1, int num2, int oper) {
int res = 0;
switch (oper) {
case '*':
res = num1 * num2;
break;
case '/':
res = num2 / num1;
break;
case '-':
res = num2 - num1;
break;
case '+':
res = num1 + num2;
break;
default:
break;
}
return res;
}
}