java數據結構之棧實現表達式求值

用棧實現了一個求簡單表達式值的算法。算法最後是一個同優先級的表達式,需要先入先出,這違背了棧先入後出的性質。最終使用遞歸解決這個問題,先把一個操作數和一個操作法pop出來,然後遞歸的pop,直到操作法棧爲空,遞歸結束。

 

package cn.agan.mystack;

import java.util.Scanner;

/**
 * 表達式計算:
 *     用棧來計算一個表達式的值 7 * 2 * 2 - 5 +1 + 4 / 2 * 3 = 30
 *     兩個棧,一個用來壓數字,一個壓入運算符,如果棧爲空就直接將運算符壓人棧中;如果要壓入的運算符優先級大於棧頂的運算符
 *     則彈出兩個數字,算完再將結果押入數字棧,棧頂運算符彈出,目的運算符繼續與下一個棧頂運算符比較。。。
 *     在壓完運算符後,依次彈出運算符,每彈出一個運算符,就彈出兩個數字進行運算,結果壓入數字棧。。。直至運算符彈出完畢。
 */
public class ExpressionCalculate {
    public static void main(String[] args) {
        ArrayStack2 digitalStack = new ArrayStack2(1024);
        ArrayStack2 operatorStack = new ArrayStack2(1024);
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String line;
        int index = 0, num1 = 0, num2 = 0, res = 0, oper = 0;
        char ch = ' ';
        while ( loop ) {
            index = 0;
            System.out.println("輸入一個表達式,給你算出表達式的值。暫時只支持+-*/ 和單位數,12+1不支持");
            System.out.println("輸入exit退出程序");
            line = scanner.nextLine().trim();
            switch (line) {
                case "exit":
                    loop = false;
                    break;
                default:
                    while (true) {
                        ch = line.substring(index, index+1).charAt(0);
                        if (operatorStack.isOper(ch)) { //運算符
                            if (!operatorStack.isEmpty()) {
                                if (operatorStack.priority(ch) <= operatorStack.priority(operatorStack.peak())) {
                                    num1 = digitalStack.pop();
                                    num2 = digitalStack.pop();
                                    oper = operatorStack.pop();
                                    res = digitalStack.cal(num2, num1, oper);
                                    digitalStack.push(res);
                                    operatorStack.push(ch);
                                } else {
                                    operatorStack.push(ch);
                                }

                            } else { //直接入棧
                                operatorStack.push(ch);
                            }

                        } else { //數字,直接入數值棧
                            digitalStack.push(ch - 48);
                        }
                        index++;
                        if (index >= line.length()) {
                            break;
                        }
                    }
//                    while (!operatorStack.isEmpty()) {
//                        num1 = digitalStack.pop();
//                        num2 = digitalStack.pop();
//                        oper = operatorStack.pop();
//                        res = digitalStack.cal(num2, num1, oper);
//                        digitalStack.push(res);
//                    }
                    res = calStack(digitalStack, operatorStack);
                    System.out.println("表達式結果爲:"+ res);
                 break;
            }
        }

    }

    //按照先入先出的順序算出棧裏面的數據
    public  static  int calStack(ArrayStack2 digitalStack, ArrayStack2 operatorStack) {
        if (operatorStack.isEmpty()) {
            return digitalStack.pop();
        }

        int num1 = digitalStack.pop();
        int oper = operatorStack.pop();
        int res = 0;
        res = digitalStack.cal(calStack(digitalStack, operatorStack), num1, oper);

        return res;
    }


}

class ArrayStack2 {
    private int maxSize ; //棧的大小
    private int[] stack;  //存儲數據的數組
    private int top = -1; //棧頂,初始化爲-1

    public ArrayStack2( int maxSize) {
        this.maxSize = maxSize;
        stack = new int[this.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;
        }

        stack[++top] = value;
    }

    //返回運算符的優先級,預定數字越大,優先級越高
    public int priority(int opr) {
        if (opr == '*' || opr == '/') {
            return 4;
        } else if (opr == '+' || opr == '-') {
            return 3;
        } 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 = num1 + num2;
                break;
            case '-':
                res = num1 - num2;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num1 / num2;
                break;
            default:
                System.out.println("獲取尚未支持的運算符");
                return 0;
        }

        return res;
    }

    //查看棧頂元素
    public int peak() {
        if (isEmpty()) {
            throw  new RuntimeException("棧空");
        }

        return stack[top];
    }

    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("棧空");
        }

        return stack[top--];
    }

    //遍歷棧,從棧頂開始顯示
    public void show() {
        if (isEmpty()) {
            System.out.println("棧空,沒有數據");
            return;
        }

        for (int i = top; i >= 0; i--) {
            System.out.printf("%d\t", stack[i]);
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章