mplement 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.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
spoilers alert... click to show requirements for atoi.
The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.
If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.
题意:实现函数atoi,将字符串转化为整型数,对于特殊情况的处理:
(1)忽略前导空白符(包括'\0'和' '),考虑第一个非空白字符序列,可由+-开头,跟着一串连续的数字,组成一个整数
(2)组成整数的字符后面可以有附加无关字符,忽略这些字符,不影响输出
(3)若第一个非空白字符序列不能构成一个整数,或字符串为空或只包含空白符,返回0
(4)若转换的整数超过整型数范围,输出INT_MAX(2147483647) 或INT_MIN(-2147483648)
分析: 细节非常多的一道题,我是根据要求一步一步来做的,面试时候要想把上面4条都考虑到,还是有难度的。
说一些需要注意的地方:
1、先遍历前导空白,找到第一个非空白符,若是数字可以直接向下判断;若是+-要看后边有没有数字,没有数字则非法;若是其他字符则也为非法
2、按位生成整数,我每次累加时乘上一个mult因子,正数mult=1,负数mult=-1,每次将结果*10,再加上当前数字即可
3、最麻烦的是判断是否超过整数范围,一开始我用long long int 存储,每次循环比较一下即可,比较容易过。但是后来一下,如果面试官将问题扩展,问将str转换为long long int,该怎么判断是否超范围呢?后来开始想一种用整型数记录并判断超范围的方法:在每次循环时,判断当前数是否大于INT_MAX/10,大于的话则把当前数加上之后就越界了;再判断INT_MAX-ret*10是否小于当前数,小于的话,加上之后也会越界,这样就能控制所有变量和中间运算结果都不会超出整型数范围了。负数类同,注意ret=0,1,-1时的情况,中间结果不要越界。
代码:
class Solution { public: int atoi(const char *str) { int len = strlen(str); int i; for(i=0; i<len && (str[i]==0 || str[i]==' '); i++) ; if(i>=len) return 0; if(str[i]!='+' && str[i]!='-' && (str[i]>'9' || str[i]<'0')) return 0; if((str[i]=='+' || str[i]=='-') && (i>=len-1 || str[i+1]>'9' || str[i+1]<'0')) return 0; int mult = 1; if(str[i]=='+') i++; if(str[i]=='-') { i++;mult=-1;} int ret=0; for(; i<len && str[i]>='0' && str[i]<='9'; i++) { int now = str[i]-'0'; if(ret>0 && (INT_MAX/10<ret || INT_MAX-ret*10<now)) { ret = INT_MAX; break; } if(ret<0 && (INT_MIN/10>ret || INT_MIN-ret*10>-now)) { ret = INT_MIN; break; } ret *= 10; ret += mult * now; } return ret; } };