LeetCode 8. String to Integer (atoi)
题目描述:
Implement atoi which converts a string to an integer.
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.
Note:
- Only the space character ’ ’ is considered as whitespace character.
- Assume we are dealing with an environment which could only store
integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. If
the numerical value is out of the range of representable values,
INT_MAX (2^31 − 1) or INT_MIN (−2^31) is returned.
Example 1:
Input: "42"
Output: 42
Example 2:
Input: " -42"
Output: -42
Explanation: The first non-whitespace character is '-', which is the minus sign.
Then take as many numerical digits as possible, which gets 42.
Example 3:
Input: "4193 with words"
Output: 4193
Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.
Example 4:
Input: "words and 987"
Output: 0
Explanation: The first non-whitespace character is 'w', which is not a numerical
digit or a +/- sign. Therefore no valid conversion could be performed.
Example 5:
Input: "-91283472332"
Output: -2147483648
Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.
Thefore INT_MIN (−231) is returned.
题目理解:
模拟实现atoi函数,将字符串转化成数字,有以下几个规则:
- 在读到字符前的所有空格全部消除
- 读到字符后若不是正负号,直接返回0值
- 默认是正数,若读到正负号则作记录
- 开始读数字后,直到读到不是数字的字符才终止
- 在转数字的过程中,若发生溢出,则根据正负号返回相应的溢出值
解题思路:
- 首先清楚空格,再进行第一个字符的判断,记录正负号,或者直接返回0
- 接着进入转换数字的循环中,判断数字可以用isdigit()函数,将ASCII码转化成整数只需要减去其与字符零’0‘的差值即可,这两点都是我自己没有注意到的,浪费了一些时间。
比较重要的就是判断溢出,这里有两种思路:
-一是我自己的思路,从之前题目中学习到,在将ans新一轮的*10之前,比较其与INT_MAX/10的大小, 之前的测试用例比较简单只要大于就默认溢出,但是还有等于的情况,在这次就要考虑,比如INT_MAX-1这个值 -二是从优秀代码中借鉴的思路,每次ans更新前都记录一下更新前的值,若更新后的值/10与之前的值不一样了, 那么就发生了溢出;若是更新后ans变成了负数,那么也认为发生了溢出。
- 最后根据符号值返回对应的ans即可。
class Solution {
public:
int myAtoi(string str) {
int len = str.size();
int i;
for(i=0;str[i]==' '&&i<len;i++){}
bool flag=true;
if(str[i]=='+'){
flag = true;
i++;
}else if(str[i]=='-'){
flag = false;
i++;
}else if(str[i]<'0'||str[i]>'9'){
return 0;
}
int ans = 0;
while(str[i]>='0'&&str[i]<='9'&&i<len){//这里用isdigit()会方便一些
if(ans>INT_MAX/10){
if(flag) {return INT_MAX;}
else {return INT_MIN;}
}else if(ans == int(INT_MAX/10)){//这里采用自己的思路,要对类似INT_MAX-1的值进行判断
if(flag){
if(str[i]>'7') {return INT_MAX;}
else{
ans = ans*10 +(str[i]-48);
break;
}
}else if(!flag){
if(str[i]>'8') {return INT_MIN;}
else{
ans = ans*10 +(str[i]-48);//48也可以用'0'代替
break;
}
}
}
else{
ans = ans*10 +(str[i]-48);
i++;
}
}
if(!flag){ans = -ans;}
return ans;
}
};
总结:
这道题类似的不知道做了多少遍了,希望能有进步。现在在按照刷题指南刷题,给自己加加油~