题解 | #把字符串转换成整数(atoi)#
把字符串转换成整数(atoi)
http://www.nowcoder.com/practice/d11471c3bf2d40f38b66bb12785df47f
题目的主要信息:
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成: 1.若干空格 2.(可选)一个符号字符('+' 或 '-')
- 数字,字母,符号,空格组成的字符串表达式
- 若干空格
方法一:
首先利用一个while循环去除空格,然后用flag保存符号位。用res保存已经转换的整数,遍历一遍字符串,将数字字符转换为整数,加到res的末尾。在遍历过程中需要注意边界情况,以下两种情况说明再添加数字将越界:
- 当res为正整数时,如果res > INT_MAX/10 || res==INT_MAX/10 && s[index]-'0' > INT_MAX%10)表示正整数超过INT_MAX,要截断
- 当res为负整数时,如果res < INT_MIN/10 || res==INT_MIN/10 && s[index]-'0' > -(INT_MIN%10)表示负整数小于INT_MAX,要截断
具体做法:
class Solution {
public:
int StrToInt(string s) {
int index = 0;
int res = 0, flag = 1;
while(s[index] == ' ') index++;
if(index < s.size() && (s[index] == '+' || s[index] == '-')) {
if(s[index] == '-'){
flag = -1;//判断符号位
}
index++;
if(!isdigit(s[index])) return 0;//符号位后没有整数部分,返回0
}
while(index < s.size() && isdigit(s[index])) {
if(flag==1){
if(res > INT_MAX/10 || res==INT_MAX/10 && s[index]-'0' > INT_MAX%10) {//正整数超过INT_MAX要截断
return INT_MAX;
}
} else{
int temp = res*flag;
if(temp < INT_MIN/10 || temp==INT_MIN/10 && s[index]-'0' > -(INT_MIN%10)) {//负整数小于INT_MIN要截断
cout<<temp<<endl;
return INT_MIN;
}
}
res = res*10+s[index]-'0';//接上当前的数字
index++;
}
return res*flag;
}
};
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串。
- 空间复杂度:,只用了常数空间。
方法二:
整体思路和方法一相同。方法二将res的类型改为long,可以储存64位整数。遍历一遍字符串,将当前数字字符拼在res之后,如果res超过了INT_MAX或INT_MIN,说明已经越界了,截断输出;否则继续遍历字符串。
具体做法:
class Solution {
public:
int StrToInt(string s) {
int index = 0;
long res = 0;
int flag = 1;
while(s[index] == ' ') index++;
if(index < s.size() && (s[index] == '+' || s[index] == '-')) {
if(s[index] == '-'){
flag = -1;//判断符号位
}
index++;
if(!isdigit(s[index])) return 0;//符号位后没有整数部分,返回0
}
while(index < s.size() && isdigit(s[index])) {
res = res*10+s[index]-'0';//接上当前的数字
index++;
if(flag==1){
if(res > INT_MAX) {//正整数超过INT_MAX要截断
return INT_MAX;
}
} else{
long temp = res*flag;
if(temp < INT_MIN) {//负整数小于INT_MIN要截断
return INT_MIN;
}
}
}
return res*flag;
}
};
复杂度分析:
- 时间复杂度:,需要遍历一遍字符串。
- 空间复杂度:,只用了常数空间。