题意理解
输入字符串,按照规则将其中的数字串转化为整数输出。
问题分析
按照题意一步一步处理。
删除前置空格,判断正负号,处理数字串(丢弃数字串后面的非数字字符),数字串转整数(处理溢出情况)
其他
本想着很难,其实按步骤思路也很顺。
3/4:复杂的处理,需要一步一步的来走,这里先处理掉空格,在处理符号,再循环抽取数字,对于溢出,先保存为无符号整数,判断是否超过无符号整数范围,然后判断是否超过有符号整数范围,最后才是正常的加符号动作。整个过程清晰明了。值得学习。
参考了libc的实现,真的好。
链接
int myAtoi(string str) {
unsigned int result = 0;
int i = 0;
//erase empty
while(str[i] == ' ')
{
i++;
}
//judge sign
int negative;
if(str[i] == '+')
{
negative = 0;
++i;
}
else if (str[i] == '-')
{
negative = 1;
++i;
}
else
negative = 0;
//cout << "sign: " << negative << endl;
unsigned int cutoff = UINT_MAX / 10; //溢出判断分解成两部分,一部分是前n位数;
unsigned int cutlim = UINT_MAX % 10; //一部分是最后一位
int overflow = 0;
char c;
for(c = str[i];c != '\0';c = str[++i]) //循环每个字符,控制条件也赋值
{
//cout << "c" << c << endl;
//保留数字
if(c >= '0' && c <= '9')
c -= '0';
else
break;
//check overflow,unsigned int
if(result > cutoff || (result == cutoff && c > cutlim))
overflow = 1;
else
{
result *= 10; //先扩倍
result += c; //再加低位数字
}
//cout << "c" << c << endl;
}
//cout << "result:" << result << endl;
//如果非符号整数的范围在有符号整数之外
if (result > (negative ? -(unsigned int) INT_MIN : (unsigned int) INT_MAX))
//就是溢出
overflow = 1;
if (overflow)
return negative ? INT_MIN : INT_MAX; //溢出直接输出最大值或最小值(根据符号判断)
return (negative ? -result : result); //最后可以直接添加符号结束
}