0%

把字符串转换成整数

题目描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0

输入描述:

1
输入一个字符串,包括数字字母符号,可以为空

输出描述:

1
如果是合法的数值表达则返回该数字,否则返回0

示例1

输入

1
2
+2147483647
1a33

输出

1
2
2147483647
0

解答

不用库函数的版本待补充

1
2
3
4
5
6
7
8
9
public int StrToInt(String str) {
int x=0;
try {
x=Integer.valueOf(str);
}catch (Exception e){
return 0;
}
return x;
}

官方题解

题目意思很明确,这道题难就难在边界的考察。如果对于一般规则的数字“字符串”转化为数字都很容易,比如:
图片说明
对于“123456”可以利用如下代码进行转化:

1
2
3
4
int ans = 0;
for (int i=0; i<str.size(); ++i) {
ans = ans * 10 + (str[i] - '0');
}

int的范围为 图片说明
如果超过了这两个范围该怎么办?
其实也很简单,首先判断这个数的正负,如果正数,超过了INT_MAX,就设置为INT_MAX,如果是负数,首先我们不考虑负号,如果超过了INT_MAX+1, 则就置为INT_MAX+1, 最后再根据正负号,来加负号。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool neg = str[i]=='-' ? true : false;
i = isdigit(str[i]) ? i : i+1;
long long ans = 0L; // 因为INT_MAX+1超过了int的范围

while (i < len && isdigit(str[i])) {
ans = ans * 10 + (str[i++]-'0');

if (!neg && ans > INT_MAX) {
ans = INT_MAX;
break; //因为此处以为最大值,所以直接break
}
if (neg && ans > 1L + INT_MAX) {
ans = 1L + INT_MAX;
break;
}
}

最后再考虑一些特殊情况即可。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
int StrToInt(string str) {
const int len = str.length();
if (len == 0) return 0;
int i = 0;
while (i < len && str[i] == ' ') { ++i; } // 排除开头的空格
if (i == len) return 0;
if (!isdigit(str[i]) && str[i] != '+' && str[i] != '-') return 0;
bool neg = str[i]=='-' ? true : false;
i = isdigit(str[i]) ? i : i+1;
long long ans = 0L;

while (i < len && isdigit(str[i])) {
ans = ans * 10 + (str[i++]-'0');

if (!neg && ans > INT_MAX) {
ans = INT_MAX;
break;
}
if (neg && ans > 1L + INT_MAX) {
ans = 1L + INT_MAX;
break;
}
}
if (i != len) return 0; // 不要此处,就是atoi()库函数的实现
return !neg ? static_cast<int>(ans) : static_cast<int>(-ans);
}
};

但是本题有个样例:
图片说明
感觉很无语。
时间复杂度:O(N)
空间复杂度:O(1)