介绍
利用数组实现的栈结构来实现加减乘除运算
代码实现
1.栈的初始化操作
package exer.stack;
import java.security.interfaces.ECKey;
public class ArrayStackCal {
//栈的大小
private int stackSize;
//创建一个容器当作栈
private int[] stack;
//栈顶指针
private int top = -1;
public ArrayStackCal(int stackSize) {
this.stackSize = stackSize;
stack = new int[stackSize];
}
/**
* 判断栈是否满了
*/
public boolean isFull() {
if (top == stackSize - 1) {
return true;
}
return false;
}
/**
* 判断栈是否为空
*/
public boolean isEmpty() {
if (top == -1) {
return true;
}
return false;
}
/**
* 数据入栈
*/
public void push(int data) {
if (!isFull()) {
top++;
stack[top] = data;
} else {
throw new RuntimeException("栈已满");
}
}
/**
* 数据弹栈
*/
public int pop() {
if (!isEmpty()) {
int value = stack[top];
top--;
return value;
}
throw new RuntimeException("栈为空");
}
/**
* 返回栈的数据总数
*/
public int length() {
return top + 1;
}
/**
* 遍历栈中的数据
*/
public void list() {
if (isEmpty()) {
throw new RuntimeException("栈为空");
}
for (int i = 0; i < top + 1; i++) {
System.out.printf("stack[%d]=%d\n", i, stack[i]);
}
}
/**
* 判断是否是字符
*/
public boolean isChar(char value) {
return value == '+' || value == '-' || value == '*' || value == '/';
}
/**
* 判断优先级大小
*/
public int isPriority(char value) {
if (value == '*' || value == '/') {
return 2;
} else if (value == '+' || value == '-') {
return 1;
} else {
throw new RuntimeException("传入运算符错误,无法完成计算");
}
}
/**
*计算两数和字符运算的结果
*/
public int compute(int num1,int num2,char c){
switch (c){
case '*':
return num1*num2;
case '+':
return num1+num2;
case '-':
return num2-num1;
case '/':
return num2/num1;
}
throw new RuntimeException("传入运算符错误,无法完成计算");
}
/**
* 返回栈顶数据
*/
public int returnDataTop(){
return stack[top];
}
}
2.加减乘除运算具体实现
/**
* @author lyj
* @date 2023-07-24
* 利用栈实现加减乘除运算
*/
@Test
public void testCal() {
String str = "89*1+9/3+6";
int result = testCalculate(str);
System.out.println(result);
}
/**
* 要设计两个栈,一个为运算符栈,来存储运算符,一个为数字栈,来存储数字
* 因此需要判断要放入数字栈还是运算符栈
* 放入数字栈需要考虑:可能数字可能是多位数,因此需要判断后一位是否是字符,进行累加
* <p>
* 放入运算符栈需要考虑:如果运算符栈为空,直接将运算符入栈即可 ,如果运算符栈不为空
* 则需要考虑运算符的优先级问题,如果准备入栈的优先级小于等于栈顶优先级,根据栈
* 先进先出的原则,应当将栈顶数据弹栈,再与数字栈的两个数进行运算,运算之后将结果放入
* 数字栈,然后将准备入栈的运算符入栈,这样是为了保证运算顺序正确 乘除在前,加减在后
*
* @param str
* @return
*/
private int testCalculate(String str) {
ArrayStackCal arrayStackCal = new ArrayStackCal(10);
ArrayStackCal arrayStackNum = new ArrayStackCal(10);
int strLength = str.length();
//做好数字拼接的准备
String value="";
for (int i = 0; i < strLength; i++) {
//取出值
char var = str.charAt(i);
//分为两种情况,是运算符或者是数字
if (arrayStackCal.isChar(var)) {
//表明是运算符
//首先判断运算符栈中是否为空
if (arrayStackCal.isEmpty()) {
//如果为空,直接将数据放入运算符栈中
arrayStackCal.push(var);
} else {
//表明运算符栈不为空,需要比较栈顶数据和准备放入数据的优先级大小
//如果栈顶优先级大于等于准备放入栈的数据优先级要先将它和数字栈中的数字进行计算
if ( arrayStackCal.isPriority(var)<= arrayStackCal.isPriority((char) arrayStackCal.returnDataTop())){
//先取出栈顶数据
char innerData = (char) arrayStackCal.pop();
//再取出数字栈的两个数据
int num1 = arrayStackNum.pop();
int num2 = arrayStackNum.pop();
//计算结果
int result = arrayStackCal.compute(num1, num2, innerData);
//将运算结果放入数字栈
arrayStackNum.push(result);
//将准备入运算符栈的字符入栈
arrayStackCal.push(var);
}else{
//如果栈顶优先级小于准备入栈的数据,直接入栈即可
arrayStackCal.push(var);
}
}
} else {
value+=var;
//表明是数字
//判断该数字是否在字符串的最后一位
if (i==strLength-1){
//这时不需要进行下面判断,由于已经是最后一位,直接放入数字栈即可
arrayStackNum.push(Integer.valueOf(value));
value="";
}
//判断该数字的下一个值是否是字符
else if (arrayStackNum.isChar(str.charAt(i+1))){
//表明下一个是字符,不需要拼接,直接入栈
arrayStackNum.push(Integer.valueOf(value));
value="";
}
}
}
//计算在运算符栈和数字栈剩下的数据
int length = arrayStackCal.length();
for (int i = 0; i < length; i++) {
//取出运算符
char c = (char) arrayStackCal.pop();
//取出最前面的两个数据
int num1 = arrayStackNum.pop();
int num2 = arrayStackNum.pop();
//计算结果
int result = arrayStackCal.compute(num1, num2, c);
//放入数字栈
arrayStackNum.push(result);
}
return arrayStackNum.pop();
}