1. 题目来源
链接:lc8. 字符串转换整数
2. 题目解析
方法一:模拟+溢出判断+溢出特判
就纯模拟题,思路:
- 去除前导连续空格。
- 正负号的判断。
- 先不考虑符号,直接进行计算。
long long
不用管,如果这个无符号的值超过了INT_MAX
则跳出循环。但是int
就需要特判了。 - 判断完了还得再特判一个
-2147483648
这个值。对于INT_MIN
是合法的,而针对于INT_MAX
是非法的。即当前res=214748364,x=8, minus = -1
那么它不会被第二个判断小于INT_MAX
给卡掉。顺利进入到res=res*10+x;
就造成了溢出!!! 天坑啊。
代码:
// 投机取巧
class Solution {
public:
int myAtoi(string s) {
int k = 0;
while (k < s.size() && s[k] == ' ') k ++;
if (k == s.size()) return 0;
int minus = 1;
if (s[k] == '-') minus = -1, k ++ ;
else if (s[k] == '+') k ++;
long long res = 0;
while (k < s.size() && s[k] >= '0' && s[k] <= '9') {
res = res * 10 + s[k] - '0';
k ++;
if (res > INT_MAX) break;
}
res *= minus;
if (res > INT_MAX) res = INT_MAX;
if (res < INT_MIN) res = INT_MIN;
return res;
}
};
// 数学判断溢出+溢出特判
class Solution {
public:
int myAtoi(string s) {
int k = 0;
while (k < s.size() && s[k] == ' ') k ++;
if (k == s.size()) return 0;
int minus = 1;
if (s[k] == '-') minus = -1, k ++ ;
else if (s[k] == '+') k ++;
int res = 0;
while (k < s.size() && s[k] >= '0' && s[k] <= '9') {
int x = s[k] - '0';
if (minus > 0 && res > (INT_MAX - x) / 10) return INT_MAX;
if (minus < 0 && -res < (INT_MIN + x) / 10) return INT_MIN;
// 特判 -2147483648 这个值,若214748364*10+8则正数res就会溢出
if (-res * 10 - x == INT_MIN) return INT_MIN;
res = res * 10 + x;
k ++;
if (res > INT_MAX) break;
}
res *= minus;
if (res > INT_MAX) res = INT_MAX;
if (res < INT_MIN) res = INT_MIN;
return res;
}
};