tag保存的是数的符号,无符号长长整型的 res 用来暂时保存字符串里的数据(不含符号位)
思路比较简单:空格都pass掉以后,如果第一个字符不是数字,返回0;
否则,这一位如果是符号,把符号存到tag,从下一位开始取数,如果没有符号位,直接开始取数;
数取完了以后(有两种情况,①后面又出现了字母 ②字符串结束了),内循环和外循环都要break,所以设置一个flag位,当内循环break了 立马外循环也break;
还有一个问题值得说明:
如果把判断溢出并返回的语句(见下方代码)放到整个函数的最后执行,那么可能字符串的数字(如"18446744073709551617")已经超过了unsigned long long的表示范围;
这个时候 硬要把他存到res里,就会发生溢出范围的问题,得到预期之外的结果("18446744073709551617"存到res里,其实会变成1,最终返回1);
把unsigned 去掉,用long long,那么超过long long的最大正数后,存进去的数会变成负数,这都可能带来错误的结果;
同时,考虑到一个数溢出了int的范围以后,并不会马上就溢出 long long,即从int_max到long long_max,还有很大的中间地带;
所以我们把判断溢出并返回的语句 放到了“res = res * 10 + int(str[j]) - 48;”以后;
代码:
class Solution {
public:
static int myAtoi(string str) {
if (!str.size()) return 0;
int i = 0, j,flag=0;
unsigned long long res=0;
char tag = '+';
for (i; i < str.size(); i++)
{
if (str[i] != ' '&&str[i] != '+'&&str[i] != '-' && (str[i] < 48 || str[i]>57))
return 0;
if (str[i] == '+' || str[i] == '-' || (str[i] >= 48 && str[i] <= 57))
{
j = i;
if (str[i] == '+' || str[i] == '-')
{
tag = str[i];
j = i + 1;
}
while (j < str.size())
{
if (str[j] >= 48 && str[j] <= 57)
{
res = res * 10 + int(str[j]) - 48;
if(res>INT_MAX) //判断溢出
{
if (tag == '+')
return INT_MAX;
else return INT_MIN;
}
j++;
if (j == str.size()) flag = 1;
}
else
{
flag = 1;
break;
}
}
}
if(flag) break;
}
if (tag == '-') res = -int(res);
return (int)res;
}
};