一、题目介绍
LeetCode:字符串转换整数 (atoi)
这个题目主要考察边界处理、溢出、容错处理相关的能力。
二、解题思路
1. 难点
a. 在转化的过程中防止溢出
解决思路:res * 10 + curVal <= INT_MAX,转化一下 res <= (INT_MAX - curVal)/10
以下为解决代码:
class Solution
{
public:
int myAtoi(string str)
{
vector<int> t_vec;
t_vec.reserve(str.length());
int minus_flag = 1;
int i = 0;
// 跳过空格和符号处理
for (; i < str.length(); ++i)
{
if (str[i] == '-')
{
minus_flag = -1;
++i;
break;
}
else if (str[i] == '+')
{
minus_flag = 1;
++i;
break;
}
else if (str[i] == ' ')
continue;
else
break;
}
int res = 0;
for (; i < str.length() && isdigit(str[i]); ++i)
{
int cur_val = str[i] - '0';
if ((INT_MAX - cur_val) / 10 < res)
{
if (minus_flag == 1) return INT_MAX;
else if (minus_flag == -1) return INT_MIN;
}
res = res * 10 + cur_val;
}
return minus_flag * res;
}
};
2. 取巧的方法
基于C++的特点,可以采用以下简单的取巧方法:
class Solution
{
public:
int myAtoi(string str)
{
int num = 0;
istringstream t_iss(str);
t_iss >> num;
if (num > INT_MAX)
return INT_MAX;
else if (num < INT_MIN)
return INT_MIN;
else
return num;
}
};
参考链接:简单C++方法
python简单解决方法,可以采用正则表达式
class Solution:
def myAtoi(self, s: str) -> int:
return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
^:匹配字符串开头
[+-]:代表一个+字符或-字符
?:前面一个字符可有可无
\d:一个数字
+:前面一个字符的一个或多个
\D:一个非数字字符
*:前面一个字符的0个或多个
max(min(数字, 2^31 - 1), -2^31) 用来防止结果越界
三、解题思路思考
1. 边界条件处理
在我们考察候选者的时候,会重点关注这类问题,可以间接的反映逻辑思维能力。
在日常工作开发中,边界条件处理需要认真的进行思考,否则代码容易出错。
以下是常见的边界条件错误:
输入数据不合法
数组越界
调用的方法抛出异常
调用其他系统接口时数据未能按要求返回
打不开数据库连接
数据库表在初始情况下没有值
运行时间过长导致超时
边界条件说起来容易,写的时侯会发现很容易落掉的。
如输入参数是指针类型:NULL的检查
如数组和容器类:是否为空,或长度是否为1…//嵌套容易的元素长度是否为0
以及string 类型:长度是否为0,1
判断条件<=,>=的时侯>和=的判断是否应该一样
最后这个在二分查找、快速排序的时候比较重要,也是大家经常出错的地方。
四、编译器的解决方法
待补充