题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
测试用例
输入str:输入一个字符串,包括数字字母符号,可以为空;
返回值int:合法的数值则返回该数字,否则返回0;
用例1:str="+2147483647"; 返回值2147483647。
用例1:str="-1a33"; 返回值0。
解决方案
正数情况下,当前值为res,待加入数字字符为c,则新的res = 10res + (c-‘0’);
正负号问题
首字符可能是 ‘+’ ‘-’,需要在遍历数字之前进行判断;
采用flag标明正负,在程序结束时返回符号正确的数值。
数值越界问题
针对int型数字上下界 [232, 232-1],我们默认使用负数来表示累加和(使用正数会漏掉INT_MIN),则 res = 10res-(c-‘0’);并用负的limit来表示最值,正负数的limit分别是 {-INT_MAX, INT_MIN} ;
在判断数值是否越界时,应保证 10 * res - (c-‘0’) >= limit ;为保证不出现越界,需要(1)先判断 10 * res 是否越界,由 10*res >= limit 得到判定条件 res >= limit/10;(2)当满足条件1后,再判断res加上个位数后是否越界,即 limit - 10 * res <= -(c-‘0’);两个条件依次满足后才能保证数字的正确性;否则均判定为非法数字,直接返回0。
class Solution {
public:
//用负数表示累加值
int StrToInt(string str) {
if(str.empty()) return 0;
//为避免出现res不能存储int_min的情况,将res设为负值进行累加
//flag用于标记正负,-1表示正(最后返回flag*res)
int res = 0, idx = 0, flag = -1;
//limit表示数值界限,正数界-INT_MAX,负数界INT_MIN
int limit = numeric_limits<int>::min() + 1;
//首先判断首位字符有没有'+''-'号,并据此调整flag和limit
if(str.at(idx)=='+' || str.at(idx)=='-'){
flag = str.at(idx)=='+'? -1 : 1;
limit -= str.at(idx)=='+'? 0 : 1;
++idx;
}
int temp;
//数字字符逐位相加
for(idx; idx<str.size(); ++idx){
if(str.at(idx)<'0' || str.at(idx)>'9') return 0;
temp = str.at(idx)-'0';
//基本条件,在负数下res要大于等于int_max/10,再去判断加上个位数的情况
if(limit/10 <= res){
//再判断加上个位数后是否越界,limit <= res*10 - temp
//即limit-res*10 <= -temp
if(limit-res*10 <= -temp){
res = res*10 - temp;
}
//越界返回最大值
else{
return flag * limit;
}
}
else{
return 0;
}
}
return flag*res;
}
};