基于栈的综合计算器的实现

思路分析

  • 通过一个index值来遍历我们的表达式
  • 如果我们发现是数字,就直接入数栈
  • 如果是符号,就分如下情况:
    • 如果发现当前符号栈为空,就直接入栈
    • 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级<=栈中的操作符,就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
    • 如果当前的符号栈优先级大于栈中的优先级,就直接入符号栈
  • 当表达式扫描完毕,就顺序的从数栈和符号栈中pop出对应的数字和符号进行运算
  • 最后在数栈中只有一个数字 就是表达式的结果
package com.ran;


public class Hello {
    public static void main(String[] args) {
        String biaodashi="32+2*6-2"; //如何处理多位数的问题
        //先创建两个栈 数栈 符号栈
        ArrayStack numStack = new ArrayStack();
        ArrayStack fuhaoStack = new ArrayStack();
        //定义相关变量
        int index=0;
        int num1;
        int num2;
        int fuhao=0;
        int res;
        char ch=' '; //将每次扫描得到的char放入ch
        String keepNum=""; //用于拼接多位数
        //开始用wile语句扫描语句
        while (true){
            //依次得到表达式中的每一个字符
            ch=biaodashi.substring(index,index+1).charAt(0);
            //判断ch是什么 然后做相应处理
            if(fuhaoStack.isfuhao(ch)){
                //如果是运算符
                //判断当前符号栈是否为空
                if(!fuhaoStack.isEmpty()){
                    //如果符号栈有操作符,就进行比较,如果当前的操作符的优先级<=栈中的操作符,就需要从数栈中pop出两个数,
                    // 再从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
                    if(fuhaoStack.youxianji(ch)<=fuhaoStack.youxianji(fuhaoStack.peek())){
                        num1=numStack.pop();
                        num2=numStack.pop();
                        fuhao=fuhaoStack.pop();
                        res=numStack.yunsuan(num1,num2,fuhao);
                        //运算结果入数栈
                        numStack.push(res);
                        //当前操作符入符号栈
                        fuhaoStack.push(ch);
                    }else {
                        //如果当前的符号栈优先级大于栈中的优先级,就直接入符号栈
                        fuhaoStack.push(ch);
                    }
                }else {
                    //如果为空直接入符号栈
                    fuhaoStack.push(ch);
                }
            }else {
                //如果是数就直接入栈
                //分析:
                //1.当处理多位数时,不能发现是一个数就入栈,因为可能是多位数
                //2.在处理数时,需要向表达式的index后再看一位,如果是数就进行扫描,如果是符号才入栈
                //3.因此我们需要定义一个变量字符串 用于拼接

                //处理多位数
                keepNum+=ch;

                //若果ch已经是表达式的最后一位,就直接入栈
                if(index==biaodashi.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else{



                    //判断下一个字符是不是数字,如果是数字则进行继续扫描,如果是运算符则入栈
                    //注意看最后一位,不是index++
                    if(fuhaoStack.isfuhao(biaodashi.substring(index+1,index+2).charAt(0))){
                        //如果后一位是运算符,则入栈
                        numStack.push(Integer.parseInt(keepNum));

                        //重要重要!!!!
                        keepNum="";
                    }
                }
            }
            //让index+1 并判断是否扫描到表达式最后
            index++;
            if(index>=biaodashi.length()){
                break;
            }
        }

        //当表达式扫描完毕,就顺序的从数栈和符号栈中pop出对应的数字和符号进行运算,最后在数栈中只有一个数字 就是表达式的结果
        while (true){
            //如果符号栈为空 则计算到最后的结果,数栈只有一个数字,这就是结果
            if (fuhaoStack.isEmpty()){
                break;
            }
            num1=numStack.pop();
            num2=numStack.pop();
            fuhao=fuhaoStack.pop();
            res=numStack.yunsuan(num1,num2,fuhao);
            numStack.push(res);
        }
        //将数栈最后一个数pop出来就是结果
        int res2=numStack.pop();
        System.out.printf("表达式%s=%d",biaodashi,res2);
    }

}
//创建栈结构
class  ArrayStack {
    public HeroNode top=null;  //数组,模拟栈,数据就放在里面

    public boolean isEmpty(){
        return top==null;
    }

    //出栈
    public int pop(){

        if(isEmpty()){
            System.out.println("kong");
            return 0;
        }
        int res= top.value;
        top=top.next;
        return res;
    }
    //入栈
    public void push(int value){
        if(isEmpty()){
            top=new HeroNode(value);
        }
        else {
            HeroNode heroNode = new HeroNode(value);
            heroNode.next=top;
            top=heroNode;
        }
    }
    //增加一个方法 可以返回当前栈顶的值,不是真正出栈
    public int peek(){
        return top.value;
    }
    //遍历
    public void list(){
        if(isEmpty()){
            System.out.println("kong");
            return;
        }
        HeroNode temp=top;
        while (true){
            System.out.println(temp.value);
            if(temp.next==null){
                break;
            }
            temp=temp.next;
        }
    }

    //返回运算符的优先级,优先级是程序员来定的,优先级使用数字表示,数字越大则优先级越高
    public int youxianji(int fuhao){
        if(fuhao=='*'||fuhao=='/'){
            return 1;
        }else if(fuhao=='+'||fuhao=='-'){
            return 0;
        }else {
            return -1; //假定只有 + - * /
        }

    }

    //判断是不是一个运算符
    public boolean isfuhao(char qq){
        return qq=='+'||qq=='-'||qq=='*'||qq=='/';
    }

    //计算方法
    public int yunsuan(int num1,int num2,int fuhao){
        int res=0; //res用于存放计算的结果
        switch (fuhao){
            case '+':
                res=num1+num2;
                break;
            case '-':
                res=num2-num1;
                break;
            case '*':
                res=num1*num2;
                break;
            case '/':
                res=num2/num1;
                break;
            default:
                break;
        }
        return res;
    }


}

class HeroNode{
    int value;
    HeroNode next;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public HeroNode(int value) {
        this.value = value;
    }
}

代码运行效果如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值