尚硅谷Java数据结构--栈实现综合计算器

代码思路✨✨✨✨✨

1,创建两个栈: nums存放表达式中的数字,oper存放表达式中的运算符

2,对表达式字符串进行遍历扫描: 

        (1)为数字 入栈nums

        (2)为运算符:oper空,直接入栈;oper不为空但是当前运算符的优先级大于oper.top(),入栈oper;当前运算符优先级小于等于oper.top()----从nums中pop出两个数字,从oper中pop出一个运算符,进行运算并将运算结果入栈nums,持续对当前运算符优先级和oper.top()进行比较,并且重复以上操作,直到符合入栈的条件,最后将当前运算符入栈oper

3,依次将nums和oper中的数字弹出,进行运算,并且将运算结果入栈nums

4,nums.top() 就是表达式的结果

代码的核心思路是:
除了当前运算符为 * / 而前一个运算符为 + - 这样的情况当前运算符可以入栈,其他情况均先计算oper.top()运算符对应的运算,再对当前运算符入栈
即: 确保了先乘除后加减的运算规则

力扣相关题目:面试题 16.26. 计算器 - 力扣(LeetCode) 

package DataStructure;

import java.util.Stack;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 86178
 * Date: 2024-02-14
 * Time: 13:38
 */
public class Calculator {
    public static void main(String[] args) {
        Stack<Integer> nums1=new Stack();
        nums1.push((int)'a');
        MyStack2 nums=new MyStack2(10);
        MyStack2 oper=new MyStack2(10);
        int n1=0;
        int n2=0;
        int op=0;
        int res=0;
        //todo 用于拼接多位数
        String keepNum="";
        String s="70+10/5-20/4+12";
        //System.out.println(s.length());
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            if(!oper.isOper(c)){
                //nums.Push(c-48);//数字直接入栈
                //todo 处理多位数
                keepNum+=c;
                //todo 判断下一个字符是不是数字 是则继续扫描
                if(i==s.length()-1){
                    nums.Push(Integer.parseInt(keepNum));
                }else{
                    if(oper.isOper(s.charAt(i+1))){
                        //如果下一位是运算符
                        nums.Push(Integer.parseInt(keepNum));
                        keepNum="";
                    }
                }
            } else{
                if(oper.isEmpty()){
                    oper.Push(c);
                }else{
                    if(oper.priority(c)> oper.priority(oper.Top())){
                        oper.Push(c);
                    }else {
                        //todo 此处应该持续判断优先级
                        // 例如 - / + 如果只判断一次 则栈中的- + 则不符合 先计算优先级大于等于自己的原则
                        while(!oper.isEmpty() && oper.priority(c)<= oper.priority(oper.Top())) {
                            n1 = nums.Pop();
                            n2 = nums.Pop();
                            op = oper.Pop();
                            res = nums.cal(n1, n2, op);
                            nums.Push(res);
                        }
                        oper.Push(c);
                    }
                }
            }
        }
        while(!oper.isEmpty()){
            n1= nums.Top();
            nums.Pop();
            n2=nums.Top();
            nums.Pop();
            op= oper.Top();
            oper.Pop();
            res=nums.cal(n1,n2,op);
            nums.Push(res);
        }
        System.out.println(nums.Top());
    }
}
//todo 先创建一个栈
class MyStack2{
    private int top;//栈顶
    private int[] StArr;//数组
    private int maxSize;//栈的大小
    public MyStack2(int max){
        maxSize=max;
        StArr=new int[max];
        top=-1;
    }
    public boolean isEmpty(){
        return top==-1;//当top=-1 为空
    }
    public boolean isFull(){
        return top==maxSize-1;
    }
    //todo 入栈
    public void Push(int n){
        if(isFull()){
            System.out.println("栈满");
            return;
        }else {
            StArr[++top]=n;
        }
    }
    //todo 出栈
    public int Pop(){
        if(isEmpty()) throw new RuntimeException("栈空");
        else{
            int ret=StArr[top];
            top--;
            return ret;
        }
    }
    //todo 返回栈顶元素
    public int Top(){
        if(isEmpty()) throw new RuntimeException("栈空");
        else{
            return StArr[top];
        }
    }
    //todo 打印栈的信息
    public void show(){
        if(isEmpty()){
            System.out.println("栈空");
            return;
        }
        System.out.println("-----------------------");
        System.out.println("top="+top);
        System.out.println("打印栈");
        for(int i=top;i>=0;i--){
            System.out.print(StArr[i]+" ");
        }
        System.out.println();
        System.out.println("-----------------------");
    }
    //todo 判断运算符号的优先级
    //在Java中 int 和 char可以进行转换 ASCII
    public int priority(int oper){
        if(oper=='+' || oper=='-'){
            return 0;
        }else if(oper=='*' || oper=='/'){
            return 2;
        }else{
            return -1;//假定只有+ - * /
        }
    }
    public boolean isOper(char c){
        return c=='+' || c=='-' || c=='*' || c=='/';
    }
    //todo 计算方法
    public int cal(int n1,int n2,int oper){
        int res=0;//计算结果
        switch (oper){
            case '+':
                res=n1+n2;
                break;
            case '-':
                res=n2-n1;
                break;
            case '*':
                res=n1*n2;
                break;
            case '/':
                res=n2/n1;
                break;
        }
        return res;
    }
}

  • 15
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值