LeetCode 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

 

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

先用最通用的(转换为后缀表达式,然后对后缀表达式求值):

class Solution {

public:

    int calculate(string s) {

        vector<long> postfix = to_postfix(s);

        int len = postfix.size();

        if (len == 0) {

            return 0;

        }

        vector<long> tmp;

        long a, b;

        for (int i=0; i<len; i++) {

            long ch = postfix[i];

            switch(ch) {

                case '+':

                    a = tmp.back();

                    tmp.pop_back();

                    tmp.back() = tmp.back() + a;

                    break;

                case '-':

                    a = tmp.back();

                    tmp.pop_back();

                    tmp.back() = tmp.back() - a;

                    break;

                default:

                    tmp.push_back(-ch);

            }

        }

        return tmp[0];

    }

    

    vector<long> to_postfix(const string& s) {

        int len = s.size();

        // operators

        vector<char> operato;

        // generated postfix experssion of this infix experssion

        vector<long> postfix;

        

        int val = 0;

        bool innum = false;

        

        for (int i=0; i<len; i++) {

            char ch = s[i];

            switch (ch) {

                case ' ':

                    // skip space

                    continue;

                case '-':

                case '+':

                    while (!operato.empty() && operato.back() != '(') {

                        postfix.push_back(operato.back());

                        operato.pop_back();

                    }

                    operato.push_back(ch);

                    break;

                case '(':

                    // just push to operato

                    operato.push_back(ch);

                    break;

                case ')':

                    // move any operato between this ')' and it's paired '('

                    while (!operato.empty() && operato.back() != '(') {

                        postfix.push_back(operato.back());

                        operato.pop_back();

                    }

                    // destroy '(' placeholder

                    operato.pop_back();

                    break;

                default:

                    if (innum) {

                        val = val * 10 + ch - '0';

                    } else {

                        val = ch - '0';

                        innum = true;

                    }

                    // look ahead

                    if (i+1 == len || s[i+1] > '9' || s[i+1] < '0') {

                        postfix.push_back(-val);

                        innum = false;

                    }

            }

        }

        

        while (!operato.empty()) {

            postfix.push_back(operato.back());

            operato.pop_back();

        }

        return postfix;

    }

};

 下面这个用递归的方式处理每个括号中的表达式,但是MLE

class Solution {

public:

    int calculate(string s) {

        int len = s.size();

        int val = 0;

        char lastop = '+';

        for (int i=0; i<len; i++) {

            char ch = s[i];

            switch(ch) {

                case ' ':

                    break;

                case '(':{

                    int cnt = 1;

                    int idx = ++i;

                    while (cnt != 0) {

                        if (s[i] == '(') {

                            cnt++;

                        } else if (s[i] == ')') {

                            cnt--;

                        }

                        i++;

                    }

                    i--;

                    int t = calculate(s.substr(idx, i - idx));

                    val = lastop == '-' ? (val - t) : (val + t);

                    

                }; break;

                case ')':{

                    

                };break;

                case '+':

                case '-':

                    lastop = ch;

                    break;

                default:

                    // numbers

                    int num = 0;

                    while ((i) < len && s[i] <= '9' && s[i] >= '0') {

                        num = num * 10 + ch - '0';

                        i++;

                    }

                    i--;

                    val = lastop == '-' ? (val - num) : (val + num);

            }

        }

        

        return val;

    }

};

 好了,来个简洁的,因为只涉及到加减法,其实我们可以把括号全部化简掉,在这个过程中应用负负得正的这些规律,正确得到多层括号内数值最终的符号:

class Solution {

public:

    int calculate(string s) {

        vector<int> sign;

        sign.push_back(1);

        

        char last_op = '+';

        int len = s.size();

        

        long val = 0;

        

        for (int i=0; i<len; i++) {

            char ch = s[i];

            switch(ch) {

                case ' ':

                    break;

                case '+':

                case '-':

                    last_op = ch;

                    break;

                case '(':

                    // enter a new sign context

                    sign.push_back(sign.back() * (last_op == '-' ? -1 : 1));

                    last_op = '+';

                    break;

                case ')':

                    // exit a sign context

                    sign.pop_back();

                    break;

                default:

                    // numbers;

                    int num = 0;

                    while (i < len && s[i] >= '0' && s[i] <= '9') {

                        num = num * 10 + s[i] - '0';

                        i++;

                    }

                    i--;

                    val += (last_op == '-'?-1:1) * sign.back() * num;

            }

        }

        return val;

    }

};

 

你可能感兴趣的:(LeetCode)