Leetcode 224 Basic Calculator 基本計算器

原題地址

https://leetcode.com/problems/basic-calculator/

題目描述

Implement a basic calculator to evaluate a simple expression string.
實現基本的計算器,計算簡單表達式的值。

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .
表達式中可能會出現括號( ),加號+減號-,非負數以及空格。

You may assume that the given expression is always valid.
假設表達式都是正確的。

Some examples:
例如:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23

解題思路

由於表達式中只有+ -兩種運算符,因此不用考慮優先級的問題,唯一需要處理的是括號帶來的計算順序問題。考慮遍歷整個字符串,當遇到( + -合法數字時,將相應字符或數字壓棧,當遇到)時,從棧中彈出運算符及數字直到與這個括號匹配的開括號爲止,並計算彈出的運算符和數字的結果,計算結束後壓棧,然後繼續遍歷表達式。

在上述過程結束後,棧中還留有一些運算符合數字,但是不再包含括號,這時彈出所有運算符和數字進行一次運算即可得到最終結果。

代碼

class Solution {
public:
    /** 簡單表達式計算 */
    int calculate(string s) { 
        stack<string> expr, nums, ops;
        int cur = 0, len = s.size();
        string tmp = "";
        while (cur < len) {
            // 獲取下一個操作數或操作符
            switch (s[cur]) {
                case ' ': break;    // 忽略空格
                case '+':           // 如果遇到特殊字符
                case '-': 
                case '(': 
                    if (tmp != "") {// 添加可能存在的操作數
                        expr.push(tmp);
                        tmp = "";
                    }
                    expr.push(tmp + s[cur]); // 添加特殊字符
                    break;
                case ')': {         // 遇到閉合括號
                    if (tmp != "") {// 添加可能存在的操作數
                        expr.push(tmp);
                        tmp = "";
                    }               // 計算最頂層的括號內的子表達式
                    int caled = calculate(expr);
                    expr.push(intToStr(caled)); // 添加到棧中
                    break;
                }
                default:    // 擴展操作數
                    tmp += s[cur];
                    break;
            }
            ++cur;
        }
        if (tmp != "") expr.push(tmp);
        return calculate(expr); // 計算
    }
private:
    /** 計算棧中最上層的括號內的表達式 */
    int calculate(stack<string>& s) {
        stack<int> nums; 
        stack<char> ops;
        string top;
        // 獲取最頂層括號內的操作數和操作符
        while (!s.empty() && (top = s.top()) != "(") {
            if (top == "+" || top == "-")
                ops.push(top[0]);
            else
                nums.push(strToInt(top));
            s.pop();
        }
        if (!s.empty()) s.pop(); // 彈出"("
        // 計算子表達式結果
        int ans = nums.top(), num;
        nums.pop();
        while (!ops.empty()) {
            num = nums.top();
            nums.pop();
            if (ops.top() == '+')
                ans += num;
            else
                ans -= num;
            ops.pop();
        }
        return ans;
    }

    int strToInt(string s) {
        int ans = 0, len = s.size();
        if (len == 0) return 0;
        int symbol = s[0] == '-' ? -1 : 1;
        for (int i = s[0] == '+' || s[0] == '-' ? 1 : 0; i < len; ++i) {
            ans *= 10;
            ans += s[i] - '0';
        }
        return ans * symbol;
    }

    string intToStr(int num) {
        if (num == 0) return "0";
        int symbol = num >= 0 ? 1 : -1;
        string s = "";
        num *= symbol;
        while (num) {
            s = (char)(num % 10 + '0') + s;
            num /= 10;
        }
        if (symbol == -1)
            s = "-" + s;
        return s;
    }
};

完整代碼 https://github.com/Orange1991/leetcode/blob/master/224/cpp/main.cpp

測試數據

(1+(4+5+2 ) - 3) + (6+8)=23
1 + 1=2
 2-1 + 2 =3
 2-(5-6) =3

2015/8/28

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