栈实现综合计算器(中缀表达式)

思路图解

在这里插入图片描述

例子分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现


/**
 * 通过数组来模拟栈
 */
class ArrayStack{

    private int size;//栈的大小
    private int[] stack;//数组模拟栈
    private int top;//栈顶

    /**
     * 构造方法 用于初始化栈
     * @param size
     */
    public ArrayStack(int size) {
        this.size = size;
        this.stack = new int[size];
        this.top = 0;
    }

    /**
     * 判断是否满栈
     * @return
     */
    public boolean isFull(){
        return size == top;
    }

    /**
     * 判断是否空栈
     * @return
     */
    public boolean isEmpty(){
        return top == 0;
    }


    /**
     * 入栈
     * @param data
     */
    public void push(int data){
        //判断是否满栈
        if(isFull()){
            System.out.println("已满,无法入栈");
            return;
        }
        stack[top] = data;
        top++;
    }

    /**
     * 出栈
     */
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("空栈,无法弹出");
        }
        top--;
        return stack[top];
    }

    public int peek(){
        int temp = top -1;
        return stack[temp];
    }

    /**
     * 遍历栈中数据
     */
    public void showStack(){
        if(isEmpty()){
            System.out.println("空栈 无法打印");
            return;
        }
        for (int i= top-1; i>=0; i--){
            System.out.println(stack[i]);
        }
    }
}
/**
 * 计算器
 */
public class Calculator {

    public static void main(String[] args) {

        //定义需要计算的表达式字符串
        String expression = "3+2*6-2";
        //创建栈
        ArrayStack numStack = new ArrayStack(10);//数字栈
        ArrayStack operStack = new ArrayStack(10);//符号栈

        int index = 0;//用于解析表达式
        while (true){
            //获取表达式的每个字符
            char ch = expression.substring(index, index + 1).charAt(0);
            if(isOpen(ch)){//如果是符号
                if(operStack.isEmpty()){//如果符号栈是空的,符号直接入符号栈
                    operStack.push(ch);
                }else{//符号栈不为空
                    //判断当前符号和符号栈栈顶的符号的优先级大小
                    if (isPriority(ch) > isPriority((char) operStack.peek()) ){//当前符号优先级大
                        operStack.push(ch);//符号栈入符号栈
                    }else {//当前符号优先级小
                        //从数字栈出栈两个数字
                        int num1 = numStack.pop();
                        int num2 = numStack.pop();
                        //从符号栈出栈一个符号
                        int oper = operStack.pop();
                        //计算结果
                        int sum = cal(num1,num2,oper);
                        //结果入数字栈
                        numStack.push(sum);
                        //当前符号符符号栈
                        operStack.push(ch);
                    }
                }
            }else{//如果是数字
                //入数字栈
                numStack.push(ch-48);
            }
            index++;
            //当表达式遍历完毕 退出循环
            if(index >= expression.length()){
                break;
            }
        }
        //表达式解析完毕,计算栈中数据
        while (true){
            //判断符号栈是否为空
            if (operStack.isEmpty()){//为空表明计算完毕
                break;
            }
            int num1 = numStack.pop();
            int num2 = numStack.pop();
            int oper = operStack.pop();
            int sum = cal(num1,num2,oper);
            numStack.push(sum);//入栈
        }
        //将数栈的最后数,pop出,就是结果
        int result = numStack.pop();
        System.out.printf("表达式 %s = %d", expression, result);

    }

    /**
     * 判断当前字符是不是操作符
     * @param ch  true 是操作符
     * @return
     */
    private static boolean isOpen(char ch){
        return ch == '+' || ch == '-' || ch == '*' || ch == '/' ;
    }

    /**
     * 判断传入的符号的优先级
     * @param oper
     * @return
     */
    private static int isPriority(char oper){
       if(oper == '*' || oper == '/'){
           return 1;
       }
       if(oper == '+' || oper == '-'){
           return 0;
       }
       return -1;
    }

    /**
     * 两个数的加减乘除运算
     * @param num1
     * @param num2
     * @param oper  符号
     * @return
     */
    private static int cal(int num1, int num2, int oper) {
        int res = 0; // res 用于存放计算的结果
        switch (oper) {
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1;// 注意顺序
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1;
                break;
            default:
                break;
        }
        return res;
    }
}

此时计算机实现完毕,但是可以发现一个问题,只能计算10以内(不包括10)的加减乘除,并且不能有小括号。如有疑问或者指教,请留言方便交流

解决多位数问题

只需要将数字入数字栈的地方做出修改即可。

numStack.push(ch-48);

修改为:

                //判断多位数的操作
                 keepNum = keepNum + ch;
                 //如果当前字符ch是表达式的最后一位,则直接入栈
                if (index == expression.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else {//不是表达式的最后一个字符
                    //判断下一个字符是不是数字,如果不是数字,则入栈
                    if (isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }

解决小括号问题,详情参考后缀表大四。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值