学习记录=>栈实现四则运算计算器
设置数字栈和符号栈;设置索引,从字符串左边开始扫描;数字则入栈;符号,若符号栈为空则入栈,若符号栈非空(情况一,要入栈的符号优先级高于符号栈栈顶元素,则入栈;情况而,优先级小于或等于符号栈栈顶元素,则数字栈pop出两个数,符号栈pop出一个符号,计算结果入数字栈, 新符号入符号栈);如上入栈,直到扫描完字符串;扫描完毕后,如上文情况二进行计算
那样不断计算,最终数字栈只会剩下一个数,其就是结果。(计算时,先弹出的数字,在计算符号的右边)
package Stack;
import java.util.Stack;
/**
* @author wl
* @version 1.0
* @date 2023/6/4 19:47
* @description 栈实现计算器
**/
public class practice1 {
public static void main(String[] args) {
String expression = "113+3*6-5";
ArrayStack numberStack = new ArrayStack(10);
ArrayStack operStack = new ArrayStack(10);
//扫描字符串所需
int index = 0;
int number1 = 0;
int number2 = 0;
int topOper = 0;
int result = 0;
//用于拼接多位数
String numberString = "";
//每次得到的char保存到ch
char ch = ' ';
while (true) {
//从左往右遍历字符串
ch = expression.substring(index, index + 1).charAt(0);
if (operStack.isOper(ch)) {
//遍历到的内容为操作符
if (!operStack.isEmpty()) {
//符号栈不为空,则进行比较
if (operStack.priority(ch) <= operStack.priority(operStack.getTopElement())) {
//入栈元素小于等于栈顶元素优先级,按规则计算后再入符号栈
//不会出现连续同级,因为遇到同级则已经被这样计算了
number2 = numberStack.pop();
number1 = numberStack.pop();
topOper = operStack.pop();
//cal()第二个参数为先弹出的那个数
result = numberStack.cal(number1, number2, topOper);
numberStack.push(result);
operStack.push(ch);
} else {
//入栈元素大于栈顶元素优先级,直接入符号栈
operStack.push(ch);
}
} else {
//符号栈为空,则符号直接入符号栈
operStack.push(ch);
}
} else {
//遍历到的内容为数字,直接入数字栈
//为处理多位数,
numberString = numberString + ch;
if (index == expression.length() - 1) {
//已经是遍历到最后一位,则直接入栈
numberStack.push(Integer.parseInt(numberString));
} else {
//表达式下一位是否仍然数字,数字则继续扫描,计算符则入栈
if (numberStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
//后一位是操作符
numberStack.push(Integer.parseInt(numberString));
//清空
numberString = "";
}
}
}
index++;
//遍历完字符串,停止遍历
//index从0开始,+1才正确
if ((index + 1) > expression.length()) {
break;
}
}
//表达式扫描完毕后的计算
while (true) {
//符号栈为空,则计算完了已经
if (operStack.isEmpty()) {
break;
}
number2 = numberStack.pop();
number1 = numberStack.pop();
topOper = operStack.pop();
//cal()第二个参数为先弹出的那个数
result = numberStack.cal(number1, number2, topOper);
numberStack.push(result);
}
System.out.println("expression计算结果:" + numberStack.pop());
}
}
/**
* 数组实现的栈
*/
class ArrayStack {
/**
* 栈大小
*/
private int maxSize;
/**
* int类型数组数组模拟栈数据,栈的数据放在此
*/
private int[] stack;
/**
* 栈顶,初始化为-1
*/
private int top = -1;
/**
* 初始化栈的大小
*/
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
//初始化存数据的数组
stack = new int[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()) {
throw new RuntimeException("栈空");
}
int value = stack[top];
//初始化弹出位置的元素
stack[top] = 0;
top--;
return value;
}
/**
* 遍历栈
*/
public void list() {
for (int i = top; i > -1; i--) {
System.out.println("当前遍历到的栈元素:" + 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 number1, int number2, int oper) {
int result = 0;
switch (oper) {
case '+':
result = number1 + number2;
break;
case '-':
result = number1 - number2;
break;
case '*':
result = number1 * number2;
break;
case '/':
result = number1 / number2;
break;
default:
break;
}
return result;
}
/**
* 获取栈顶元素,但不pop出
*/
public int getTopElement() {
if (isEmpty()) {
throw new RuntimeException("当前栈为空");
}
return stack[top];
}
}