栈实现综合计算器

  • 使用栈完成表达式的计算思路分析
    1. 通过一个index索引值,遍历表达式
    2. 如果发现扫描到的是一个数字,就直接加入数栈
    3. 如果发现扫描到的是一个符号,分三种情况:
      1. 当前符号栈空,则直接入栈
      2. 当前符号栈有操作符,就进行比较:
        1. 如果当前的操作符优先级小于或等于符号栈中的操作符,则从数栈中pop取出两个数,和从符号栈中pop取出一个操作符,进行运算,然后将运算得到的结果放回数栈中,和将当前要入栈的操作符(那个优先级较大的)入栈,并把运算过的运算符移除掉
        2. 反之,如果当前的操作符优先级大于符号栈的操作符,则直接符号栈
    4. 当表达式扫描完后,就顺序的从数栈和符号栈中pop出相应的数和符号,后pop的数减去先pop的数,然后将运算结果放回数栈
    5. 最后在数栈中只有一个数字,就是表达式的结果

代码实现

  • 先创建一个数组模拟栈
//定义一个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());
    }
}

原文地址:http://www.cnblogs.com/container-simple/p/16905352.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性