题目要求
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
解题分析
其实字符串转化成数字的关键步骤大家都知道:
r
e
s
=
r
e
s
∗
10
+
s
t
r
[
i
]
−
′
0
′
res = res*10 + str[i] - '0'
res=res∗10+str[i]−′0′
这个问题的难点在于考虑条件的全面性:
首先输入的合法性:
(1)输入的字符串是不是合法长度,如空字符串,不合法返回0
(2)字符串是不是在0-9之间的数字,不合法返回0
其次在输入合法的时候,考虑边界条件:
(1)数据上下溢出,如果设置结果是int型,但是转换结果超过了int的表示范围则报错,所以我们设置结果为long long型。
(2)只有正负号,有无正负号;有正负号的时候题目默认在字符串第一位,所以我们只要用一个变量读取字符串第一位从而来标识正负即可,
(3)错误标志输出统一返回0
主要代码c++
// 输出实例最大为 +2147483647 = 2^31 - 1 是32位操作系统中最大的符号型整型常量
// 所以结果可以设为 int 型
// 如果考虑大数问题的话,可以设置res为long long 型
class Solution {
public:
int StrToInt(string str) {
int size = str.size();
if(size<=0) return 0;
int symbol = 1,long long res = 0; // 符号和结果
// 判断符号,符号一般都是在第一位
if(str[0] == '+')
symbol = 1, str[0] = '0'; // 设置为0实际上是方便遍历
else if(str[0] == '-')
symbol = -1, str[0] = '0';
for(int i = 0; i < size; ++i)
{
//判断数字是不是合法的
if(str[i]<'0'||str[i]>'9')
{
res = 0;
break;
}
res = res*10 + str[i] - '0'; // 转换核心,防止有进位
}
return res*symbol; // 如果只有正负号也输出0
}
};
总结
其实算法不难的一道题,但是很多边界条件导致了我们可能无法考虑全面而做不出来,实际上还有一点,我们把不合法的输入和‘0’的返回结果都设置成0,这在返回树枝上看不出不同的,可是实际逻辑却有着很大的不同,所以为了避免这种情况,我们可以设置一个全局变量来表示我们返回的0到底是合法的字符’0‘的转换,还是不合法的输入的返回结果。