LeetCode OJ——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) {
        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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值