JAVA 数据结构-06 (2) 栈结构的应用 简易计算表达式的计算(中缀表达式)

JAVA 数据结构学习-06 栈

JAVA 数据结构-06 (1)栈的基本数据结构实现(数组实现,链表实现)
JAVA 数据结构-06 (3) 栈结构的应用 前 中 后缀三种表达式 中缀表达式转后缀表达式 逆波兰计算器实现和算法思路

2. 栈结构的应用(表达式与计算器)

2.1 简易计算表达式的计算(中缀表达式)

70*2*2-5+1-5-3+4

实现思路:

  • 设置2个栈结构,一个数栈numStack只用来保存数字;一个符号栈operStack只用来保存符号.
  • 通过一个index值来遍历我们的表达式;
  • 如果发现index值是一个数字,就直接入符号栈;
  • 如果发现扫描到一个符号:分为一下三种情况:
    • 如果符号栈为空,就直接入栈
    • 如果符号栈不为空且当前index扫描的操作符优先级小于或等于栈顶的操作符,就需要从数栈中pop出2个数据,从符号栈中pop出一个符号,执行二元运算(减法和除法需要注意谁减/除谁);将得到的结果入数栈,然后在将当前操作符压入符号栈中.
    • 如果符号栈不为空且当前index扫描的操作符优先级大于栈顶的操作符,就直接入栈.
  • 当表达式扫描完毕时,数栈中会存储表达式中的数字和优先级较高的运算中间量,符号栈中会存储优先级从栈顶开始递减的操作符;
  • 因此可用直接按符号栈的顺序进行计算,顺序的从符号栈中pop出一个操作符,从数栈中pop出2个数字,执行完运算后将运算结果压回数字栈;
  • 当操作符栈为空时,数栈中栈顶的数字就是最终运算结果.

准备栈结构:(java底层会将char转换为int,因此可以直接比较char和int)

​ 添加判断是否是 操作符, 优先级, 执行计算 三个方法

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

    public ArrayStack(int maxSize) {
    
    
        this.maxSize = maxSize;
        this.stack = new int[maxSize];
    }

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

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

    public int getTop(){
    
    
        if(isEmpty()){
    
    
            throw new RuntimeException("栈空");
        }
        return stack[top];
    }

    public void push(int data){
    
    
        if(isFull()){
    
    
            System.out.println("栈满,无法压入数据");
            return;
        }
        top++;
        stack[top] = data;
    }

    public int pop(){
    
    
        if(isEmpty()){
    
    
            throw new RuntimeException("栈为空,无法取出数据");
        }
        int value = stack[top];
        top --;
        return value;
    }

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

    //判断是否是操作符
    //char 底层也是转换为int 所有可用直接进行比较
    public boolean isOper(int value){
    
    
        return value == '+' || value == '-' || value == '*' || value == '/';
    }

    //返回操作符的优先级 */优先级高于+-
    public int priority(int value){
    
    
        if(value == '*' || value == '/'){
    
    
            return 1;
        }
        if(value == '+' || value == '-'){
    
    
            return 0;
        }
        return -1;
    }

    //执行计算
    public int calculation (int num1,int num2,int oper){
    
    
        int res = 0;
        switch (oper){
    
    
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num1 - num2;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num1 / num2;
                break;
        }
        return res;
    }
}

思路实现:


public class Caculator {
    
    
    public  static void main(String args[]){
    
    
        //1.创建过程中需要使用的变量
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack operStack = new ArrayStack(10);
        String expression = "70+2*6-4";
        int num1;
        int num2;
        int oper;
        int res = 0;
        int index = 0;
        char ch = ' ';
        String number= "";
        while (true){
    
    
            //获取ch
            ch = expression.charAt(index);
            if(numStack.isOper(ch)){
    
    
                //是符号进行下一步判断
                if(operStack.isEmpty()){
    
    
                    //直接进栈
                    operStack.push(ch);
                }else {
    
    
                    if(operStack.priority(ch) <= operStack.priority(operStack.getTop())){
    
    
                        //需要从数栈中pop出2个数据,从符号栈中pop出一个符号,执行二元运算(减法和除法需要注意谁减/除谁);
                        //将得到的结果入数栈,然后在将当前操作符压入符号栈中.
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res = numStack.calculation(num2, num1,oper);
                        numStack.push(res);
                        operStack.push(ch);
                    }else {
    
    
//                    直接入栈.
                        operStack.push(ch);
                    }
                }
            } else {
    
    

                number += ch;
                if(index == expression.length() -1){
    
    
                    numStack.push(Integer.parseInt(number));
                }else {
    
    
                    //处理多位数,需要看index位置的后一位是否还是数字,如果是,就需要进行拼接.如果是操作符,则直接入栈
                    if(operStack.isOper(expression.charAt(index+1))){
    
    
                        //直接将string入栈
                        numStack.push(Integer.parseInt(number));
                        number = "";
                    }
                }
            }
            index++;
            if(index >= expression.length()){
    
    
                break;
            }
        }
        //数据处理完成.执行计算
        while (true){
    
    
            if(operStack.isEmpty()) break;
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.calculation(num2, num1,oper);
            numStack.push(res);
        }

        System.out.println("最后的计算结果为:"+numStack.pop());

    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44634197/article/details/108552118
今日推荐