LeetCode OJ——Basic Calculator

来源:互联网 发布:淘宝女内衣表模板 编辑:程序博客网 时间:2024/05/29 03:46

题目:
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) {        stack<string> stk;        string tmp, ss;        ostringstream oss;        //s.erase(0, s.find_first_not_of(" ")); // 去掉头部空格        //s.erase(s.find_last_not_of(" ") + 1); // 去掉尾部空格        vector<string> vec_s;        for (unsigned i = 0; i < s.length(); i++)   //去掉空格        {            if (s[i] != ' ')            {                ss.push_back(s[i]);            }        }        s = ss;        unsigned i = 0;        ss.clear();        while (i < s.length())      //将s分裂成新的字符串,例 "1 - 1 2 + ( 3 - 34)"        {                           //转换成"1", "-", "12", "+", "(", "3", "-", "34", ")"            //ss.clear();            if (isdigit(s[i]))            {                ss.push_back(s[i]);                i++;            }            else{                if (!ss.empty())                {                    vec_s.push_back(ss);                    ss.clear();                }                ss.push_back(s[i]);                vec_s.push_back(ss);                ss.clear();                i++;            }        }        if (!ss.empty())        {            vec_s.push_back(ss);            ss.clear();        }        ss.clear();        if (vec_s.size() == 0)     //容器为空,表明s不存在非空格字符        {            return 0;        }        else if (vec_s.size() == 1)    //容器长度为1,表明s只含有数字字符        {            return atoi(vec_s[0].c_str());        }        else{            tmp.push_back(s[0]);            stk.push(vec_s[0]);            for (unsigned i = 1; i < vec_s.size(); i++)            {                if (vec_s[i] == "(")     //当前字符为'('                {                    tmp.clear();                    tmp.push_back('(');                    stk.push(tmp);                    //stk.push(vec_s[i]);                }                else if (vec_s[i] == "+")     //当前字符为+                {                    //栈顶元素为数字,+号后面的字符s[i+1](+号后面一定存在字符,否则字符串不合法)也为数字,即+号前后都为数字可运算                    if (isdigit(tmp[tmp.size()-1]) && isdigit(vec_s[i+1][vec_s[i+1].size()-1]))                    {                        //tmp.pop_back();       //此时tmp中原先存储的数字并没有消去                        oss.str("");                        oss << atoi(tmp.c_str()) + atoi(vec_s[i+1].c_str());                        tmp = oss.str();                        stk.pop();                        stk.push(tmp);  //将运算后的数字入栈                        i++;                    }                    else{                        tmp.clear();    //每次入栈前都将tmp清空                        tmp = vec_s[i];                        stk.push(tmp);                    }                }                else if (vec_s[i] == "-")     //当前字符为-                {                    //栈顶元素为数字,-号后面的字符s[i+1](-号后面一定存在字符,否则字符串不合法)也为数字,即-号前后都为数字可运算                    if (isdigit(tmp[tmp.size()-1]) && isdigit(vec_s[i + 1][vec_s[i + 1].size() - 1]))                    {                        oss.str("");                        oss << (atoi(tmp.c_str()) - atoi(vec_s[i + 1].c_str()));     //-号前后元素都为数字,故可进行运算                        tmp = oss.str();                        stk.pop();                        stk.push(tmp);  //将运算后的数字入栈                        i++;                    }                    else{                        tmp.clear();                        tmp = vec_s[i];                        stk.push(tmp);                    }                }                else if (isdigit(vec_s[i][vec_s[i].size() - 1]))   //当前字符为数字                {                        tmp.clear();                        tmp = vec_s[i];                        stk.push(tmp);                }                else if(vec_s[i] == ")")     //当前字符为')',表示栈中一定存在'('                {                    tmp = stk.top();  //栈顶元素为当前()中运算的值                    stk.pop();      //删除运算值                    stk.pop();      //此时,删除的是'('                    if (!stk.empty())//若此时的栈不为空                    {                        if (stk.top() == "+") //删除的(号前是+号                        {                            stk.pop();  //先把加号出栈                            oss.str("");                            oss << (atoi(stk.top().c_str()) + atoi(tmp.c_str()));  //加号前面的数字加上旧的tmp值                        }                        if (stk.top() == "-")  //删除的(好前面是-号                        {                            stk.pop();  //先把减号出栈                            oss.str("");                            oss << (atoi(stk.top().c_str()) - atoi(tmp.c_str()));  //减号前面的数字减上旧的tmp值                        }                        tmp.clear();                        tmp = oss.str();                        stk.pop();  //把+或-号前参与运算的数也去掉                    }                    stk.push(tmp);  //将运算后的值入栈                }                else      //当前字符为空格                {                    ;                }            }            return atoi(stk.top().c_str());        }    }};

结果:
这里写图片描述


思路:


  • 第一步是将字符串中的空格字符去掉

  • 第二步则是将字符串分裂,例s=”1 - 1 2 + ( 3 - 34)”,则分裂后的子串放置在容器中vec_s : “1”, “-“, “12”, “+”, “(“, “3”, “-“, “34”, “)”

  • 第三部是对入栈出栈操作进行运算:
      (a) 当遍历的容器中的字符串为“(”号时,入栈

      (b) 当该字符串为数字时,入栈

   (c) 当该字符串为”+”时,则考虑是否可以进行运 算。因为字符串中只存在+或 -, 因此运算符优先级 相同,只要碰到可以运算的字符串,则可先进行计 算。tmp中存储的是stk.top()的值,即当前字符串 的前一字符串。当”+”号前后均是数字时则可进行 运算。所以要考虑后一字符串是否也为数字, isdigit(vec_s[i + 1][vec_s[i + 1].size() - 1])只对后 一字符串的最后一位字符是否为数字进行判别,其 理由是vec_s[i+1]只有可能是 “(” 或 “)”或“[- ]1XXX”,若最后一位为数字其结果必然也是数 字。同理,isdigit(tmp[tmp.size()-1])。

  (d)当为”-“时,同”+”原理。

  (e)当为”)”时,则栈中一定存在”(“,切”( )”构成一&个封闭的运算,则该()种的式子一定已经运算过,即栈中存储结构为 ….,(, 数字 。则此时应该出栈2次,将(和数字均出栈。由于合法的字符 中“(”的前面要么是+/-;要么前面没有任何有效字符符,即(已经在最前面。若前面是+/-,则可以更进一步,按照(c)或(d)计算。

  (f)将容器遍历完,栈中也只剩最后运算后的结果,返回结果即可

总结:
算法时间复杂度还比较大,算法还需改进。小菜鸟,加油!!!↖(^ω^)↗

0 0
原创粉丝点击