背景
在做这道题目时,被如何判断溢出难住了,因为我没做过这样的🤣,故看题解
建议大家先看看题目,再继续向下。
得到答案后特此记录。
答案
方法一
res是之前叠加的部分,curChar是将要添加的那一位
if (res > INT_MAX / 10 || (res == INT_MAX / 10 && (curChar - '0') > INT_MAX % 10)) {
return INT_MAX;
}
if (res < INT_MIN / 10 || (res == INT_MIN / 10 && (curChar - '0') > -(INT_MIN % 10))) {
return INT_MIN;
}
这里我只看得懂 ||
号后面的那段表达式,意思就是:若已经累加的部分 res
等于INT_MAX
截断最后一位后的值,且新要累加的那位数大于INT_MAX
最后一位便意味着溢出。这很好理解。
INT_MIN
类似上面。。。。。。
但感觉太过于冗长,故找到一种更加简便的方法
方法二(最佳)
if (res > (INT_MAX - curChar) / 10) {
return sign?INT_MAX:INT_MIN;
}
上图就是INT_MAX
的值,以此为例
- 先举个
curChar
<= 7的例子
先将INT_MAX
减去curChar
,然后再削去最后一位,因为curChar
<= 7,故削去最后一位的值为214748364,即上图res
部分,只要res
部分不大于214748364,就不会溢出,若res
部分大于214748364,就意味着res + curChar
将会溢出。
- 若
curChar
> 7,然后再削去最后一位,则(INT_MAX - curChar) / 10
的值)小于 214748364,只要res
部分不大于该值,就不会溢出,若res
部分大于该值,就意味着res
+curChar将会溢出。 - 那如何判断负溢出呢?
因为INT_MIN
和INT_MAX
的值分别为[-2147483648 , 2147483647]
,忽略符号部分,只看数字部分,只要数字部分大于2147483647,就意味着数字部分的值等于或大于2147483648(即溢出) ,因此根据符号位便可判断负溢出或者是正溢出。
完整代码
class Solution
{
public:
int myAtoi(string str)
{
int len = str.size();
// 去除前导空格
int index = 0;
while (index < len)
{
if (str[index] != ' ')
{
break;
}
index++;
}
if (index == len)
{
return 0;
}
bool sign = true;
// 处理第 1 个非空字符为正负符号,这两个判断需要写在一起
if (str[index] == '+')
{
index++;
}
else if (str[index] == '-')
{
sign = false;
index++;
}
// 根据题目限制,只能使用 int 类型
int res = 0;
while (index < len)
{
if (str[index] < '0' || str[index] > '9')
{
break;
}
int curChar = str[index] - '0';
if (res > (INT_MAX - curChar) / 10)
{
return sign ? INT_MAX : INT_MIN;
}
res = res * 10 + curChar;
index++;
}
return sign ? res : -res;
}
};