经常会遇到类似于“把字符串转成32位的整数(-2^31-1 ~ ? ” 2^31),如果超出这个范围就返回0,假设不存在64位的long整数“。按照题目要求是只能使用int型数来进行处理。所以我们只能在循环里提前一步进行判断,如果下一个操作会溢出,那么则直接返回0.
下面介绍两种方式。
方式一:
int len = str.length();
// str.charAt(i) 方法回去检查下标的合法性,一般先转换成字符数组
char[] charArray = str.toCharArray();
// 1、去除前导空格
int index = 0;
while (index < len && charArray[index] == ' ') {
index++;
}
// 2、如果已经遍历完成(针对极端用例 " ")
if (index == len) {
return 0;
}
// 3、如果出现符号字符,仅第 1 个有效,并记录正负
int sign = 1;
char firstChar = charArray[index];
if (firstChar == '+') {
index++;
} else if (firstChar == '-') {
index++;
sign = -1;
}
// 4、将后续出现的数字字符进行转换
// 不能使用 long 类型,这是题目说的
int res = 0;
while (index < len) {
char currChar = charArray[index];
// 4.1 先判断不合法的情况
if (currChar > '9' || currChar < '0') {
break;
}
// 题目中说:环境只能存储 32 位大小的有符号整数,因此,需要提前判:断乘以 10 以后是否越界
if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - '0') > Integer.MAX_VALUE % 10)) {
return Integer.MAX_VALUE;
}
if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currChar - '0') > -(Integer.MIN_VALUE % 10))) {
return Integer.MIN_VALUE;
}
// 4.2 合法的情况下,才考虑转换,每一步都把符号位乘进去
res = res * 10 + sign * (currChar - '0');
index++;
}
return res;
}
如上所示,使用 ”if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - ‘0’) > Integer.MAX_VALUE % 10))“。如果条件成立则表示溢出。
第二种方式就简单一点:
public int myAtoi(String s) {
int sign = 1, ans = 0, index = 0;
char[] array = s.toCharArray();
if (index < array.length && (array[index] == '-' || array[index] == '+')) {
sign = array[index++] == '-' ? -1 : 1;
}
while (index < array.length && array[index] <= '9' && array[index] >= '0') {
int digit = array[index++] - '0';
if (ans > (Integer.MAX_VALUE - digit) / 10) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
ans = ans * 10 + digit;
}
return ans * sign;
}
如上所示,直接使用 if (ans > (Integer.MAX_VALUE - digit) / 10) 进行判断,如果大于则表示溢出。