栈实现综合计算器
- 使用栈完成表达式的计算思路分析
- 通过一个index索引值,遍历表达式
- 如果发现扫描到的是一个数字,就直接加入数栈
- 如果发现扫描到的是一个符号,分三种情况:
- 当前符号栈空,则直接入栈
- 当前符号栈有操作符,就进行比较:
- 如果当前的操作符优先级小于或等于符号栈中的操作符,则从数栈中pop取出两个数,和从符号栈中pop取出一个操作符,进行运算,然后将运算得到的结果放回数栈中,和将当前要入栈的操作符(那个优先级较大的)入栈,并把运算过的运算符移除掉
- 反之,如果当前的操作符优先级大于符号栈的操作符,则直接符号栈
- 当表达式扫描完后,就顺序的从数栈和符号栈中pop出相应的数和符号,后pop的数减去先pop的数,然后将运算结果放回数栈
- 最后在数栈中只有一个数字,就是表达式的结果
代码实现
- 先创建一个数组模拟栈
//定义一个ArrayStack表示栈
class ArrayStack{
private int maxSize;
private int[] stack;
private int top=-1;
//构造器
public ArrayStack(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()){
throw new RuntimeException("栈空");
}
int value=stack[top];
top--;
return value;
}
//显示栈,遍历时从栈顶开始显示数据
public void showStack(){
if (isEmpty()){
System.out.println("栈空,无数据");
return;
}
for (int i= top;i>-1;i--){
System.out.printf("stack[%d]:%d\n",i,stack[i]);
}
}
}
- 再写几个方法,方便实现逻辑调用判断
/**
* 根据输入一个运算符,判断其优先级,如果参数优先级大于符号栈中的运算符,则直接入符号栈,
* 否则,从数栈拿出两数,和从符号栈中拿出符号,进行运算,将计算结果放入数栈,
* 将要加入的运算符替换掉用来运算的符号,并放入符号栈
* @param opera 传入一个运算字符
* @return 返回一个数字代表运算符的优先级
*/
public int priority(int opera){
if (opera=='*'||opera=='/'){
return 1;
}else if (opera=='+'||opera=='-'){
return 2;
}else {
return -1;
}
}
/**
* 判断是否该值是不是运算符
* @param value 传入一个运算表达式的一个值
* @return 返回true,则是一个运算符
*/
public boolean isOpera(int value){
return value=='*'||value=='/'||value=='+'||value=='-';
}
/**
* 计算方法,根据运算符的优先级进行出栈
* @param num1 数字1
* @param num2 数字2
* @param opera 运算符
* @return 返回计算后的结果
*/
public int cal(int num1,int num2,int opera){
int result =0;//声明变量result,方便将计算结果保存
switch (opera){
case '+':
result = num1 + num2;
break;
case '-':
result =num2 - num1;
break;
case '*':
result = num1*num2;
break;
case '/':
result = num2/num1;
default:
break;
}
return result;
}
- main方法里具体实现逻辑判断
package com.guodaxia.stack;
/**
* @ author Guo daXia
* @ create 2022/11/18
*/
public class Calculator {
public static void main(String[] args) {
//先静态判断 一个表达式 的逻辑运算
String expression ="3+2*3-2";
//创建两个栈,数栈和符号栈
ArrayStack numStack = new ArrayStack(10);
ArrayStack operaStack = new ArrayStack(10);
//定义需要的相关变量
int index = 0;//用于扫描
int num1 = 0;
int num2 = 0;
int opera = 0;
int result = 0;
char ch = ' ';//将每次扫描后得到的char保存到ch中
//使用while循环扫描expression
while (true) {
//依次得到 每一个字符
ch = expression.substring(index, index + 1).charAt(0);
//判断ch是什么,然后做相应的处理
if (operaStack.isOpera(ch)) {//如果是运算符的话
//判断当前符号栈是否为空
if (!operaStack.isEmpty()) {//如果当前符号栈不空
//判断当前运算符的优先级
int str = operaStack.peek();//得到符号栈中运算符
if (operaStack.priority(ch) <= operaStack.priority(str)) {//如果要进栈的符号优先级小于str
//数栈pop出两个数,符号栈pop出str运算符,进行计算,并将结果在数栈里,将要进栈的符号进栈
num1 = numStack.pop();
num2 = numStack.pop();
opera = operaStack.pop();
result = numStack.cal(num1, num2, opera);
numStack.push(result);
operaStack.push(ch);
} else {
operaStack.push(ch);
}
} else {
operaStack.push(ch);
}
}else {//不是运算符,是数字
numStack.push(ch -48);//底层编码是Ascii
}
//让index + 1,判断是否扫描到expression最后
index++;
if (index>=expression.length()){
break;
}
}
//当扫描完expression表达式后,就顺序的从数栈和符号栈中pop出,进行运算
while (true){
if (operaStack.isEmpty()){//如果符号栈为空,则计算到最后的结果,数栈中只剩一个数字,那就是运算答案
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
opera = operaStack.pop();
result = numStack.cal(num1, num2, opera);
numStack.push(result);
}
System.out.printf("表达式%s = %d",expression,numStack.pop());
}
}
标签:return,符号,实现,opera,运算符,int,计算器,数栈,综合
From: https://www.cnblogs.com/container-simple/p/16905352.html