1. 程式人生 > >[LeetCode] Basic Calculator III 基本計算器之三

[LeetCode] Basic Calculator III 基本計算器之三

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 .

The expression string contains only non-negative integers, +-*/ operators , open ( and closing parentheses )

 and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid. All intermediate results will be in the range of [-2147483648, 2147483647].

Some examples:

"1 + 1" = 2
" 6-4 / 2 " = 4
"2*(5+5*2)/3+(6/2+8)" = 21
"(2+6* 3+5- (3*14/7+2)*5)+3"=-12

Note: Do not use the eval built-in library function.

這道題是基本計算器系列的第三道,前兩道分別為Basic CalculatorBasic Calculator II,區別是,第一道只有加減法跟括號,第二道只有加減乘除法,而這第三道既有加減乘除法又有括號運算。其實做過前兩道題的話,那麼這道題也就沒什麼問題,因為把前兩道題的解法綜合一下就是這道題的解法啦。由於此題既有括號,又有乘除法,我們知道括號是優先順序最高的,但是好就好在我們可以將括號裡的內容當作一個整體呼叫遞迴函式來處理。而其他部分,就跟第二道一模一樣了。我們還是分情況來處理遍歷,我們需要幾個變數,num表示當前的數字,curRes表示當前的結果,res為最終的結果,op為操作符號,初始化為'+'。當遇到數字的時候,我們將num自乘以10並加上這個數字,這是由於可能遇到多位數,所以每次要乘以10。當遇到括號的時候,這裡就有一個小trick,由於表示可能會有括號巢狀括號,所以我們如果搜尋右括號的話,就有可能使得括號沒有正確的匹配上,所以我們用一個變數cnt,遇到左括號自增1,遇到右括號自減1,當cnt為0的時候,說明括號正好完全匹配,這個trick在驗證括號是否valid的時候經常使用到。然後我們就是根據左右括號的位置提取出中間的子字串呼叫遞迴函式,返回值賦給num。如果遇到符號,或者是最後一個位置的字元時,我們根據op的值對num進行分別的加減乘除的處理,結果儲存到curRes中。然後再次判讀如果op是加或減,或者是最後一個位置的字元時,將curRes加到結果res中,並且curRes重置為0。最後將當前字元c賦值給op(注意這裡只有當時最後一個位置的字元時,才有可能不是運算子號,不過也不要緊了,因為遍歷已經結束了),num也要重置為0,參見程式碼如下:

class Solution {
public:
    int calculate(string s) {
        int n = s.size(), num = 0, curRes = 0, res = 0;
        char op = '+';
        for (int i = 0; i < n; ++i) {
            char c = s[i];
            if (c >= '0' && c <= '9') {
                num = num * 10 + c - '0';
            } else if (c == '(') {
                int j = i, cnt = 0;
                for (; i < n; ++i) {
                    if (s[i] == '(') ++cnt;
                    if (s[i] == ')') --cnt;
                    if (cnt == 0) break;
                }
                num = calculate(s.substr(j + 1, i - j - 1));
            }
            if (c == '+' || c == '-' || c == '*' || c == '/' || i == n - 1) {
                switch (op) {
                    case '+': curRes += num; break;
                    case '-': curRes -= num; break;
                    case '*': curRes *= num; break;
                    case '/': curRes /= num; break;
                }
                if (c == '+' || c == '-' || i == n - 1) {
                    res += curRes;
                    curRes = 0;
                }
                op = c;
                num = 0;
            }
        }
        return res;
    }
};

類似題目:

參考資料: