用栈实现 简单的表达式的计算 中缀表达式

创建两个栈,一个用来存储数据,一个用来存储符号。

当我们计算表达式的时候一般都是先算乘除然后从左到右进行计算,比如下面的式子。
17 * 2 * 2 +15 -1 + 2 - 3

我们先算17*2就算变成34,然后在算加之前会用34*2然后其余从左到右计算。

我们用两个栈来模拟,首先将1 7放入数据栈,将 * 放入运算符栈。
接着将2放入数据栈
在这里插入图片描述
截下来在存入*之前我们进行比较,如果新存入的运算符的优先级小于等于已经在栈里面的我们就先将栈中的元素取出,从数据栈中取出两个元素进行运算将运算后的数据重新存入栈中。请添加图片描述在这里插入图片描述
然后将2存入数据栈。接下来是+,同理进行判断。请添加图片描述

最后将运算的68,和接下来的+存入。后面都是都一个道理,如果运算符中有多个运算符,直到要存入的运算符优先于顶部的运算符为止。

代码如下

栈代码

package stack.Arrstack;

public class ArrStack {
    private int maxSize;
    private int top;
    private int[] stack;

    public ArrStack(int maxSize) {
        top = -1;
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    public int peek(){

        return stack[top];
    }


    public boolean isEmpty() {
        return top == -1;
    }

    public boolean isFull() {
        return top == maxSize - 1;
    }

    public void push(int num) {
        if (isFull()){
            System.out.println("栈已满");
            return;
        }
        top++;
        stack[top]=num;
    }

    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("栈为空");
        }
        int temp = stack[top];
        top--;
        return temp;
    }

    public void show(){
        if (isEmpty()){
            System.out.println("栈为空");
            return;
        }
       for (int i = top ;i>=0;i--){
           System.out.printf("stack[%d]=%d\n",i,stack[i]);
       }
    }

}

运算demo

package stack.Arrstack;

import java.util.Scanner;

public class ComputedExpression {
    public static void main(String[] args) {
        //定义一个数据栈,一个运算符栈
        ArrStack numbers = new ArrStack(10);
        ArrStack operator = new ArrStack(10);
        //接受表达式
        String expression;
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入表达式");
        expression = sc.nextLine();
        //将表达式保存在字符数组中
        byte[] exp = expression.getBytes();
        //用来连接非个位数
        String s ="";
        //遍历字符数组,将数据压入栈
        for (int i = 0; i < exp.length; i++) {
            //如果是运算符
            if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') {
                while (true) {
                    //判断优先级,优先级高 或者栈为空则直接压入栈
                    if (operator.isEmpty() || priority(exp[i]) > priority(operator.peek())) {
                        operator.push(exp[i]);
                        break;
                    } else {
                    //不为空 则计算 在压入栈
                        int num1 = numbers.pop();
                        int num2 = 0;
                        if (!numbers.isEmpty()) {
                            num2 = numbers.pop();
                        }
                        int e  = operator.pop();
                        int res = Compute(num1, num2,e);
                        numbers.push(res);
                    }

                }
            }else{
                //如果为数值,进行拼接,因为一次只能取一个字符数组
                
                s= s + (exp[i]-'0');
                //判断是否到达末尾
                if (i+1<exp.length) {
                    //如果待压入的数值的后一位不为运算符则拼接,否则直接压入
                    if (exp[i + 1] == '+' || exp[i + 1] == '-' || exp[i + 1] == '*' || exp[i + 1] == '/') {
                        numbers.push(Integer.parseInt(s));
                        s = "";

                    }
                }else{
                    numbers.push(Integer.parseInt(s));
                }
            }

        }
        while (true){
            //运算符栈 不为空就计算,为空退出
            if (operator.isEmpty()){
                break;
            }
            int e  = operator.pop();
            int num1 = numbers.pop();
            int num2 = 0;
            if (!numbers.isEmpty()) {
                num2 = numbers.pop();
            }
            int res = Compute(num1, num2, e);
            numbers.push(res);
        }

        System.out.println("结果是"+numbers.pop());




    }
    
    //自定义优先级

    public static int priority(int num) {
        if (num == '+' || num == '-') {
            return 0;
        }
        if (num == '*' || num == '/') {
            return 1;
        }
        throw new RuntimeException("表达式有误");
    }
//          计算
    public static int Compute(int num1, int num2, int ope) {

        if (ope == '+') {
            return num1  + num2;
        }
        if (ope == '-') {
            return num2 - num1 ;
        }
        if (ope == '*') {
            return num1*num2;
        }
        if (ope == '/') {
            return num2  / num1 ;
        }

        throw new RuntimeException("计算有误");
    }
}

纯手写 代码有很大的可能有错误,请大家纠正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vivien_o.O

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值