練習-棧在表達式求值中的應用

題目:輸入字符串格式的算數(shù)表達式,計算出結果

思路:創(chuàng)建兩個棧,一個棧用來存儲數(shù)字,另一個棧用來存儲運算符。然后從左到右遍歷字符,遇到數(shù)字壓入數(shù)字棧,遇到運算符需要與運算符棧的棧頂元素進行比較。
如果比棧頂運算符的優(yōu)先級高,則直接入棧,如果比棧頂運算符的優(yōu)先級低,或者優(yōu)先級相同,則取出兩個數(shù)字,一個運算符,進行完運算后將結果存入數(shù)字棧中,再將符號入棧。

1.未考慮表達式中包含括號的情況。

    public int calculate(String str) {
        char[] array = str.toCharArray();

        Stack<String> numStack = new Stack<>();
        Stack<String> symbolStack = new Stack<>();

        //存儲運算符的等級
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("*", 2);
        map.put("/", 2);
        map.put("+", 1);
        map.put("-", 1);

        // 進棧
        int result = 0;
        for (int i = 0; i < array.length; i++) {
            String chToStr = new String(array[i] + "");

            if (map.containsKey(chToStr)) {
                if (symbolStack.size() == 0) {
                    symbolStack.push(chToStr);
                    continue;
                }

                // 判斷當前符號與棧頂符號的優(yōu)先級
                String lastElement = symbolStack.peek();
                if (map.get(lastElement) >= map.get(chToStr)) {
                    // 計算,并將結果壓棧
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());
                    String sym = symbolStack.pop();

                    if ("*".equals(sym)) {
                        result = num1 * num2;
                    } else if ("/".equals(sym)) {
                        result = num2 / num1;
                    } else if ("+".equals(sym)) {
                        result = num2 + num1;
                    } else if ("-".equals(sym)) {
                        result = num2 - num1;
                    }

                    numStack.push(result + "");
                }
                symbolStack.push(chToStr);

            } else {
                //如果是數(shù)字,還要判斷是不是個位數(shù)。如果不是個位數(shù),需要進行拼接后再存儲
                if (i > 0 && isNum(new String(array[i - 1] + ""))) { 
                    String pop = numStack.pop();
                    numStack.push(pop + chToStr);
                } else {
                    numStack.push(chToStr);
                }
            }
        }

        // 出棧
        int temp = 0;
        int size = symbolStack.size();
        for (int i = 1; i <= size; i++) {
            int num1 = Integer.parseInt(numStack.pop());
            int num2 = Integer.parseInt(numStack.pop());
            String sym = symbolStack.pop();

            if ("*".equals(sym)) {
                temp = num1 * num2;
            } else if ("/".equals(sym)) {
                temp = num2 / num1;
            } else if ("+".equals(sym)) {
                temp = num2 + num1;
            } else if ("-".equals(sym)) {
                temp = num2 - num1;
            }

            numStack.push(temp + "");
        }

        return Integer.parseInt(numStack.pop());

    }

    private boolean isNum(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

2.考慮表達式中包含括號的情況。

    public int calculate(String str) {
        char[] array = str.toCharArray();

        Stack<String> numStack = new Stack<>();
        Stack<String> symbolStack = new Stack<>();

        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("(", 1);
        map.put("+", 2);
        map.put("-", 2);
        map.put("*", 3);
        map.put("/", 3);

        // 進棧
        for (int i = 0; i < array.length; i++) {
            String chToStr = new String(array[i] + "");

            if ("(".equals(chToStr)) { // 如果是左括號,直接進棧
                symbolStack.push(chToStr);
                continue;
            } else if (")".equals(chToStr)) { // 如果是右括號,兩邊都出棧,并進行計算,直到遇到左括號

                int size = symbolStack.size();
                for (int j = 0; j < size; j++) {
                    String sym = symbolStack.pop();
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());

                    if ("(".equals(sym)) {
                        numStack.push(num2 + "");
                        numStack.push(num1 + "");
                        break;
                    }

                    int operation = operation(num1, num2, sym);

                    numStack.push(operation + "");
                }

            } else if (map.containsKey(chToStr)) {

                if (symbolStack.size() == 0) {
                    symbolStack.push(chToStr);
                    continue;
                }

                // 判斷當前符號與棧頂符號的優(yōu)先級
                String lastElement = symbolStack.peek();
                if (map.get(lastElement) >= map.get(chToStr)) {
                    // 計算,并將結果壓棧
                    int num1 = Integer.parseInt(numStack.pop());
                    int num2 = Integer.parseInt(numStack.pop());
                    String sym = symbolStack.pop();

                    int res = operation(num1, num2, sym);

                    numStack.push(res + "");
                }
                symbolStack.push(chToStr);

            } else {
                if (i > 0 && isNum(new String(array[i - 1] + ""))) {
                    String pop = numStack.pop();
                    numStack.push(pop + chToStr);
                } else {
                    numStack.push(chToStr);
                }
            }
        }

        // 出棧
        int size = symbolStack.size();
        for (int i = 1; i <= size; i++) {
            int num1 = Integer.parseInt(numStack.pop());
            int num2 = Integer.parseInt(numStack.pop());
            String sym = symbolStack.pop();

            int res = operation(num1, num2, sym);

            numStack.push(res + "");
        }

        // System.out.println(numStack);
        // System.out.println(symbolStack);

        return Integer.parseInt(numStack.pop());

    }

    private int operation(int num1, int num2, String sym) {
        int temp = 0;

        if ("*".equals(sym)) {
            temp = num1 * num2;
        } else if ("/".equals(sym)) {
            temp = num2 / num1;
        } else if ("+".equals(sym)) {
            temp = num2 + num1;
        } else if ("-".equals(sym)) {
            temp = num2 - num1;
        }
        return temp;
    }

    private boolean isNum(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容