*實現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;
運行結果如下: