动手实现atoi函数—— Leetcode(8)
题目链接:8. String to Integer (atoi)
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
题目
实现将string
转化为int
的atoi
函数。这题需要充分考虑各种不规范输入的情况,主要有以下几种情况:
- 忽略前面的所有空格直到非空格出现。从该字符开始,有可能是正负号,然后紧跟着一系列数字。
- 在数字的尾部有可能有一些无关的附加字符,也需要忽略它们。
- 如果第一个非空格字符不是有效数(即不是+-或者数字),则返回0。
- 如果string为空,或者仅有空格,则返回0。
- 如果最终结果超过int的范围,则返回int的最大/最小值。
提供几个测试样例:
//Input:"2147483648" Expected:2147483647 //溢出的情况
//Input:"+" Expected:0 //不合法的情况
//Input:"+-2" Expected:0 //不合法的情况
// Input: " 123" //有空格的情况
// Input:"-123" //有负数的情况
// Input:"+123" //有+号的情况
解法
先给出我自己折腾的一个解法:
int my_atoi(string str){
const int INT_MAX = 0x7fffffff;
const int INT_MIN = 0x80000000;
int len = str.size();
int index = 0;
while(str[index] == ' ' && index < len){
index ++; // 跳过空格
}
int sign = 1; //符号位
long l = 0;
for(int i=index; i< len; ++i){
if(str[i] == '-' || str[i] == '+')
if('0'<= str[i+1] && str[i+1] <= '9')
sign = (str[i] == '-')? -1 : 1;
else
return 0;
else if('0'<= str[i] && str[i] <= '9')
{
l = l * 10 + (str[i] - '0'); // 字符0对应的10进制为48,可以直接减去48
if(l * sign > INT_MAX){
return INT_MAX;
}
else if (l * sign < INT_MIN){
return INT_MIN;
}
}
else
break;
}
return l * sign;
}
主要思路就是:从左向右,先忽略空格;然后空格之后第一位有三种可能:
- 如果是“+-”号,则第二位必须是数字才记上正负号,否则返回0;
- 如果是数字,直到遇到非数字结束;
- 如果不是上述情况,则返回0。
这边再给出一个简洁的写法,具体思路类似。
int my_atoi(string str){
long result = 0;
int indicator = 1;
for(int i = 0; i<=str.size();)
{
i = str.find_first_not_of(' ');
if(str[i] == '-' || str[i] == '+')
indicator = (str[i++] == '-')? -1 : 1;
while('0'<= str[i] && str[i] <= '9')
{
result = result*10 + (str[i++]-'0');
if(result*indicator >= INT_MAX) return INT_MAX;
if(result*indicator <= INT_MIN) return INT_MIN;
}
return result*indicator;
}
}
注:原先for(int i = 0; i<=str.size();)
中并不包含等号,会导致空串时无返回值的错误。因此加上等于号。