栈实现中缀表达式

public class ArrayStack {

    private int maxSize;
    private int[] arr;
    private int top = -1;

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

    public static void main(String[] args) {

        ArrayStack stack = new ArrayStack(6);
        stack.push(9);
        stack.push(2);
        stack.push(5);
        stack.push(8);
        stack.push(7);
        System.out.println("===========");
        stack.traverse();
        System.out.println("--------------");
        System.out.println(stack.pop());
        System.out.println("++++++++++++++");
        stack.traverse();
        System.out.println("******************");
        // 14
        System.out.println(stack.calculator("7*2-2-5+10-5+8/4"));
    }

    /**
     * 截取一个字符,判断是数字还是运算符
     * 若字符是数字,判断是否是最后一个字符,若是直接入数字栈
     * 如不是最后一位,则判断后一位是否是数字,若是则拼接继续循环,若不是直接入数字栈
     * 若字符是运算符,运算符栈为空则直接入栈,不为空则判断当前运算符的优先级是否小于等于栈顶运算符的优先级
     * 若小于等于,说明栈顶的优先级高,应该先行运算,则弹出数字栈前两位数字,再弹出运算符栈栈顶元素,进行计算
     * 若大于,则说明当前运算符优先级高,直接入运算符栈
     * 一直循环,直至表达式末尾
     * 表达式解析完毕,则从数字栈弹出两个元素,运算符栈弹出一个元素,计算结果存入数字栈,继续循环,直至运算符栈为空退出循环
     * @param expression 表达式
     * @return
     */
    public int calculator(String expression) {
        int num1;
        int num2;
        int index = 0;
        char c;
        String concatStr = "";
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack2 operStack = new ArrayStack2(10);
        while (true) {
            c = expression.substring(index, index + 1).charAt(0);
            if (isOper(c)) {
                if (operStack.isEmpty()) {
                    operStack.push(c);
                } else {
                    if (getPriority(c) <= getPriority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        char pop = operStack.pop();
                        int calc = calc(num1, num2, pop);
                        numStack.push(calc);
                        operStack.push(c);

                    } else {
                        operStack.push(c);
                    }
                }
            } else {
                concatStr += c;
                if (index == expression.length() - 1) {
                    numStack.push(Integer.parseInt(concatStr));
                } else {
                    if (isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        numStack.push(Integer.parseInt(concatStr));
                        concatStr = "";
                    }
                }

            }
            index++;
            if (index >= expression.length()) {
                break;
            }
        }
        while (true) {
            if (operStack.isEmpty()) {
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            char pop = operStack.pop();
            int calc = calc(num1, num2, pop);
            numStack.push(calc);
        }
        return numStack.pop();
    }

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

    public int pop() {
        if (isEmpty()) {
            System.out.println("栈已空");
            throw new RuntimeException("栈已空");
        }
        return arr[top--];
    }

    public void traverse() {
        for (int i = top; i >= 0; i--) {
            System.out.println(arr[i]);
        }
    }

    public int peek() {
        return arr[top];
    }

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

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

    public static boolean isOper(char oper) {
        return oper == '+' || oper == '-' || oper == '*' || oper == '/';
    }

    /**
     * 减法和除法需要注意,例如9-2,9在栈底,2在栈顶
     * 即num1=2,num2=9,所以是num2-num1
     *
     * @param num1
     * @param num2
     * @param oper
     * @return
     */
    public static int calc(int num1, int num2, char 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 static int getPriority(char oper) {
        if (oper == '*' || oper == '/') {
            return 1;
        }
        if (oper == '+' || oper == '-') {
            return 0;
        }
        return -1;
    }
}

class ArrayStack2 {
    private int maxSize;
    private char[] arr;
    private int top = -1;

    public ArrayStack2(int maxSize) {
        this.maxSize = maxSize;
        arr = new char[maxSize];
    }

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

    public char pop() {
        if (isEmpty()) {
            System.out.println("栈已空");
            throw new RuntimeException("栈已空");
        }
        return arr[top--];
    }


    public char peek() {
        return arr[top];
    }

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

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

    public int getTop() {
        return top;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值