*实现atoi()
函数其实LeetCode 的一道中等题,具体题目如下:
这道题目的基本思路并不难,麻烦的在于各种边界条件的判断,整个转换必须处理好如下几个问题:
- 开始连续的空格后接数字
- 正负号的处理
- 出现其他非数字的字符
- 溢出问题(题目规定只能存储32位数字,因此无法使用
long long
等) (关键问题)
实现代码如下:
class Solution {
public:
int myAtoi(string str) {
if(!isdigit(str[0])&&!isspace(str[0])&&str[0]!='-'&&str[0]!='+'){return 0;}//第一个字符如何处理
int flag=0,res=0,cnt=0;//flag表示征服,res表示转换的结果,cnt表示目前处理了几个数字字符
for(int i=0;i!=str.size();++i)
{
if(isspace(str[0])&&isspace(str[i])&&cnt==0)continue;出现连续空格处理方法
if(str[i]=='-'&&flag==0){flag=-1;cnt++;continue;} //第一个负号,后第n次出现的负号处理方法
if(str[i]=='+'&&flag==0){flag=1;cnt++;continue;}//正号处理
if(!isdigit(str[i]))return res; //出现非数字的字符,立即返回已有的结果
else
{
if(flag==0) flag=1; //如果没有出现正号和负号,那么默认为正号
int r=str[i]-'0';//字符转换成数字
if(res>INT_MAX/10||((res==INT_MAX/10)&&(r>7)))return INT_MAX;
if(res<INT_MIN/10||((res==INT_MIN/10)&&(flag*r<-8)))return INT_MIN;
res=res*10+flag*r; //注意不要忘记符号位flag
cnt++; //处理过的数字,主要用来处理空格出现在数字之间的情况
}
}
return res; //返回
}
};
首先我们分析一下如何处理溢出问题:
res=res*10+flag*r;
溢出只可能出现在上面这句代码,因此我们必须做一些处理:
假设res为正数:
如果res>INT_MAX/10
,那么res*10必然会溢出
如果res=INT_MAX/10
,那么r必须小于或等于INT_MAX的个位数7,否则也会溢出。
上面两句话转换成代码:
if(res>INT_MAX/10||((res==INT_MAX/10)&&(r>7)))return INT_MAX;
同样的res为负数,也有类似的分析方法(唯一区别INT_MIN个位为8)
if(res<INT_MIN/10||((res==INT_MIN/10)&&(flag*r<-8)))return INT_MIN;
运行结果如下: