Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 227. Basic Calculator II #227

Open
grandyang opened this issue May 30, 2019 · 3 comments
Open

[LeetCode] 227. Basic Calculator II #227

grandyang opened this issue May 30, 2019 · 3 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

Implement a basic calculator to evaluate a simple expression string.

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

Example 1:

Input: "3+2*2"
Output: 7

Example 2:

Input: " 3/2 "
Output: 1

Example 3:

Input: " 3+5 / 2 "
Output: 5

Note:

  • You may assume that the given expression is always valid.
  • Do not use the eval built-in library function.

Credits:
Special thanks to @ts for adding this problem and creating all test cases.

 

这道题是之前那道 Basic Calculator 的拓展,不同之处在于那道题的计算符号只有加和减,而这题加上了乘除,那么就牵扯到了运算优先级的问题,好在这道题去掉了括号,还适当的降低了难度,估计再出一道的话就该加上括号了。不管那么多,这道题先按木有有括号来处理,由于存在运算优先级,我们采取的措施是使用一个栈保存数字,如果该数字之前的符号是加或减,那么把当前数字压入栈中,注意如果是减号,则加入当前数字的相反数,因为减法相当于加上一个相反数。如果之前的符号是乘或除,那么从栈顶取出一个数字和当前数字进行乘或除的运算,再把结果压入栈中,那么完成一遍遍历后,所有的乘或除都运算完了,再把栈中所有的数字都加起来就是最终结果了,参见代码如下:

 

解法一:

class Solution {
public:
    int calculate(string s) {
        long res = 0, num = 0, n = s.size();
        char op = '+';
        stack<int> st;
        for (int i = 0; i < n; ++i) {
            if (s[i] >= '0') {
                num = num * 10 + s[i] - '0';
            }
            if ((s[i] < '0' && s[i] != ' ') || i == n - 1) {
                if (op == '+') st.push(num);
                if (op == '-') st.push(-num);
                if (op == '*' || op == '/') {
                    int tmp = (op == '*') ? st.top() * num : st.top() / num;
                    st.pop();
                    st.push(tmp);
                }
                op = s[i];
                num = 0;
            } 
        }
        while (!st.empty()) {
            res += st.top();
            st.pop();
        }
        return res;
    }
};

 

在做了 Basic Calculator III 之后,再反过头来看这道题,发现只要将处理括号的部分去掉直接就可以在这道题上使用,参见代码如下:

 

解法二:

class Solution {
public:
    int calculate(string s) {
        long res = 0, curRes = 0, num = 0, n = s.size();
        char op = '+';
        for (int i = 0; i < n; ++i) {
            char c = s[i];
            if (c >= '0' && c <= '9') {
                num = num * 10 + c - '0';
            }
            if (c == '+' || c == '-' || c == '*' || c == '/' || i == n - 1) {
                switch (op) {
                    case '+': curRes += num; break;
                    case '-': curRes -= num; break;
                    case '*': curRes *= num; break;
                    case '/': curRes /= num; break;
                }
                if (c == '+' || c == '-' || i == n - 1) {
                    res += curRes;
                    curRes = 0;
                }
                op = c;
                num = 0;
            } 
        }
        return res;
    }
};

 

Github 同步地址:

#227

 

类似题目:

Basic Calculator III

Basic Calculator

Expression Add Operators

 

参考资料:

https://leetcode.com/problems/basic-calculator-ii/

https://leetcode.com/problems/basic-calculator-ii/discuss/63003/Share-my-java-solution

https://leetcode.com/problems/basic-calculator-ii/discuss/63004/17-lines-C++-easy-20-ms

https://leetcode.com/problems/basic-calculator-ii/discuss/63031/Simple-C++-solution-beats-85-submissions-with-detailed-explanations

 

LeetCode All in One 题目讲解汇总(持续更新中...)

@lld2006
Copy link

lld2006 commented Jun 14, 2020

这两个solution都是错的,处理不了 2+3*-4这样的expression, 学习了一下正确的做法, 利用>>,化繁为简, 省去了很多处理

class Solution{
public:
int calculate(string s){
istringstream iss('+'+s);
int ans=0, prev=0, n=0;
char op;
while(iss>>op>>n){
if(op =='+' || op =='-'){
ans = (op =='+'? ans+n:ans-n);
n = (op=='+'?n:-n);
}else{
n =(op==''? prevn: prev/n);
ans -= prev-n;
}
prev = n;
}
return ans;
}
};

@grandyang
Copy link
Owner Author

这两个solution都是错的,处理不了 2+3*-4这样的expression, 学习了一下正确的做法, 利用>>,化繁为简, 省去了很多处理

class Solution{
public:
int calculate(string s){
istringstream iss('+'+s);
int ans=0, prev=0, n=0;
char op;
while(iss>>op>>n){
if(op =='+' || op =='-'){
ans = (op =='+'? ans+n:ans-n);
n = (op=='+'?n:-n);
}else{
n =(op=='_'? prev_n: prev/n);
ans -= prev-n;
}
prev = n;
}
return ans;
}
};

这个 test case 合不合法题目中也没明确说明,题目只是说了:
You may assume that the given expression is always valid.

@Nannew
Copy link

Nannew commented Aug 28, 2021

这两个solution都是错的,处理不了 2+3*-4这样的expression, 学习了一下正确的做法, 利用>>,化繁为简, 省去了很多处理

class Solution{
public:
int calculate(string s){
istringstream iss('+'+s);
int ans=0, prev=0, n=0;
char op;
while(iss>>op>>n){
if(op =='+' || op =='-'){
ans = (op =='+'? ans+n:ans-n);
n = (op=='+'?n:-n);
}else{
n =(op=='_'? prev_n: prev/n);
ans -= prev-n;
}
prev = n;
}
return ans;
}
};

能通过 基本就是官方解法2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants