中缀表达式计算器

用中缀表达式写一个计算器,可以实现加减乘除的运算。不支持括号

基本思路:
1通过一个index索引来遍历我们的表达式
2如果我们发现是单个数字,就直接入栈
否则判断下一位是否还是数字,如果是数字就采用字符串拼接的方式取值
3如果是符号位,当符号位为空时,直接入栈
如果有符号进行优先级比较
4表达式扫描完毕。计算值并且输出
一些细节的思路要看代码,有些地方不太好表述
很容易有小bug,我也是调试了好几次的。

在这里插入代package 栈.栈实现综合计算器;
//只能进行加减乘除的计算器,本质上是中缀表达式

public class Calculator {
    public static void main(String[] args) {
        String expression ="13-9/3+4";
        ArrayStack numStack =new ArrayStack(10);
        ArrayStack operStack=new ArrayStack(10);
        //定义需要的相关变量
        int index = 0;//用于扫描
        int num1=0;
        int num2=0;
        int oper=0;
        int res =0;//保存结果
        String keepNum ="";//拼接多位数用的字符串
        char ch= ' ';//将每次扫描得到的char保存到ch
        while (true){
           ch=expression.charAt(index);
           //判断ch,进行处理
            if(operStack.isOper(ch)){//如果是运算符
                if(!operStack.isEmpty()){
                    //如果符号栈不为空,进行优先级比较
                    //如果当前符号优先级小于等于栈中的符号操作符
                    //就取出栈中的操作符,和两个数栈中的数字进行运算,结果压入数栈
                    //当前符号再压入符号栈。
                    if(operStack.priority(ch)<=operStack.priority(operStack.peek())){
                         num1=numStack.pop();
                         num2=numStack.pop();
                         oper=operStack.pop();
                         res=numStack.cal(num1,num2,oper);
                         //把结果压入数栈
                          numStack.push(res);
                          //判断压入的符号是否仍然优先级小于等于栈顶的符号
                           //不做这个判断,会有错误
                            //比如 13-9/3+4,不做下面的操作最后表达式会变成13-(3+4)
                            //这个不好解释,大概是最后两个符号是优先级相同的话,不进行下面的  
                            //语句会有错误
                        while (operStack.priority(ch)<=operStack.priority(operStack.peek())){
                              num1=numStack.pop();
                              num2=numStack.pop();
                              oper=operStack.pop();
                              res=numStack.cal(num1,num2,oper);
                              //把结果压入数栈
                              numStack.push(res);
                              if(operStack.isEmpty()){
                                  break;
                              }

                           }
                          operStack.push(ch);
                    }else {
                        //如果当前操作符优先级小于栈中直接入栈
                        operStack.push(ch);
                    }
                }else {
                    //如果为空直接入栈
                    operStack.push(ch);
                }

            }else {
                //如果是单个数字,直接入栈,当处理多位数时,不能直接入栈
                //需要判断后面是否还是数字
                //因此要定义一个字符串用于拼接
                //如果是char类型表示成int类型的数字,要减去48
                //int类型表示char类型可以直接表示,当没有精度损失
                //char是一个字节的整数类型数据
                keepNum+=ch;
                //如果已经是expression的最后一位,就不进行下面的代码,否则会越界
                if(index==expression.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else {
                    //判断下一个字符是不是数字
                    if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        //如果是操作符,就入栈
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";//清空keepNum
                    }
                }

            }
            index++;
            if(index>=expression.length()){
                break;
            }

        }
        //扫描结束,顺序的从数栈和符号栈中输出数据,并且运算
        while (true){
            if(operStack.isEmpty()){
                break;//符号栈为空时,计算完毕
            }
            num1=numStack.pop();
            num2=numStack.pop();
            oper=operStack.pop();
            res=numStack.cal(num1,num2,oper);
            numStack.push(res);
        }
        System.out.println("结果:"+numStack.pop());

    }

}


class  ArrayStack{
    private int maxSize;
    private int[] stack;
    private int top= -1;

    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack =new int[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()){
            System.out.println("栈已空");
            throw new RuntimeException("栈空");
        }
        int value= stack[top];
        top--;
        return value;
    }
    //遍历栈,从栈顶开始输出
    public void show(){
        if(isEmpty()){
            System.out.println("栈空");
        }
        for (int i = top; i >=0 ; i--) {
            System.out.println(stack[i]);
        }
    }
    //返回运算符的优先级
    //使用数字表示,数字越大,优先级越高
    //int类型是可以和char类型比较的,因为char类型本身也是整形数据表示的
    public int priority(int oper){
        if(oper=='*'||oper=='/'){
            return 1;
        }else if(oper=='+'||oper=='-'){
            return 0;
        }else {
            return -1;//假定只有加减乘除
        }
    }
    //判断是不是一个运算符
    public boolean isOper(char val){
        return val=='+'||val=='-'||val=='*'||val=='/';
    }
    //计算
    //
    public int cal(int num1,int num2,int oper){
        int res =0;
        switch(oper){
             case '+':
                res=num2+num1;
                break;
            case '-':
                 res=num2-num1;//注意顺序
                 break;
            case '*':
                 res=num2 *num1;
                 break;
            case '/':
                res=num2/num1;
                break;
            default:
                break;
         }
         return res;
    }
    //查看栈顶元素
    public int peek(){
        return stack[top];
    }
}码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值