Basic Calculator II -- leetcode

来源:互联网 发布:手机淘宝退货怎么退 编辑:程序博客网 时间:2024/04/28 10:00

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7" 3/2 " = 1" 3+5 / 2 " = 5

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



算法一,先做乘除,后做加减

如果只有+-,处理起来是非常简单。从左到右,获得一个整数,进行累加就可以了。

进行两趟扫描。

第一趟做乘除运算:

1. 当遇到一个数,其前如果是+-,则暂不做处理。将其存入队列中。

2. 当遇到一个数,其前如果是*/,则将其与队尾的元素作乘除运算,必将结果修改队尾元素。

第二趟做加减运算,

只需要对队列中的数做累加处理即可。


class Solution {public:    int calculate(string s) {        vector<int> exp;        char op = '+';        for (int i=0; i<s.size(); i++) {            if (isdigit(s[i])) {                int num = 0;                while (i<s.size() && isdigit(s[i])) {                    num = num * 10 + s[i] - '0';                    ++i;                }                --i;                if (op == '+' || op == '-')                    exp.push_back((44 - op) * num); // + is 43, - is 45, in ascii                else                     exp.back() = op == '*' ? exp.back() * num : exp.back() / num;            }            else if (s[i] != ' ')                op = s[i];        }                int ans = 0;        for (auto item: exp)            ans += item;                return ans;    }};


那么有没有改进空间呢,比如一趟完成。请看算法二。


算法二,两阶段提交。

当得一个整数这个数前面的操作符后,分成两阶段提交到最终结果中。

第一阶段,将数提交到变量mul中。因为接下来可能是一个剩除操作,所以不能提交到最终结果中。暂存在中间结果。

第二阶段,当得到操作符是+-,此时,我们知道前面的mul,可以提交到最终结果了。


更详细的步骤描述为:

1. 当得到操作符为+ - 时,此时,我们知道+ - 前面的数(mul)可以提交到最终结果了。

    提交后,同时,将当前的整数,提交到mul中,因为接下来的符号有可能* /。 

2. 当得到的操作符为* /时,此时,我们被乘(除)数,已经在mul中了。只需要和mul做乘除运算即可。


对输入串添加两个+号,可以做到在退出循环之前,将最后一个整数提交到最终结果中。省去了退出循环时的处理。


class Solution {public:    int calculate(string s) {        int ans = 0;        int mul = 0, num = 0;        char op = '+';        s.append(2, '+');        for (auto ch: s) {            if (isdigit(ch))                num = num * 10 + ch - '0';            else if (ch != ' ') {                if (op == '+' || op == '-') {                    ans += mul;                    mul = (44 - op) * num; // + is 43, - is 45, in ascii                }                else if (op == '*')                    mul *= num;                else                    mul /= num;                                num = 0;                op = ch;            }        }        return ans;    }};


我也将此算法贴在leetcode讨论中了。如果你觉得此算法还不错,欢迎进去帮我点个赞吧。
https://leetcode.com/discuss/58092/share-my-solution-it-is-very-simple
0 0