首页 > 其他 > 详细

LeetCode Basic Calculator

时间:2015-06-10 06:30:43      阅读:162      评论:0      收藏:0      [点我收藏+]

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 Basic Calculator

原文:http://www.cnblogs.com/lailailai/p/4565007.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!