《把字符串转换成整数》
题意:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
这个代码是牛客上一位大佬的,但是大佬的注解不全,我没看太懂,直到我自己把注解写的详细一些才看明白,我就把我写的注解也放上来,方便大家看明白。代入值建议可以试着用最大的正整数(2147483647)带入。
//这个方法可以判断溢出,即数字大于2147483647时,输出0;
//或者数字小于-2147483648时,输出0;
public int StrToInt(String str) {
if (str == null)
return 0;
int result = 0;
boolean negative = false;//是否负数
int i = 0, len = str.length();
/**
* limit 默认初始化为 负的 最大正整数 ,假如字符串表示的是正数
* 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,
* 判断是否溢出
* 注意,int最大值为:2147483647 int最小值为:-2147483648
* 超过该范畴,即为溢出,那么就返回0。
*/
int limit = -Integer.MAX_VALUE; //limit = -2147483647 最小的INT型负数是-2147483648,因此无溢出,可以用int表示。
int multmin;
int digit;
if (len > 0) {
char firstChar = str.charAt(0);//首先看第一位
if (firstChar < '0') { // Possible leading "+"&nbs***bsp;"-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;//在负号的情况下,判断溢出的值就变成了整数的 最小负数了
} else if (firstChar != '+')//第一位不是数字和-只能是+
return 0;
if (len == 1) // Cannot have lone "+"&nbs***bsp;"-"
return 0;
i++;
}
//limit要么等于-Integer.MAX_VALUE=-2147483647,要么等于Integer.MIN_VALUE=-2147483648。
multmin = limit / 10; //如果结果值是正数,此时multmin为:-214748364;如果是负数,此时multmin为:-214748364。两者相同
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = str.charAt(i++)-'0';//char转int
if (digit < 0 || digit > 9)//0到9以外的数字
return 0;
//判断溢出
if (result < multmin) { //假设现在i到了最后一位,i=len-1,假设此时result正好是-214748364
return 0; //如果小于-214748364,即-214748365,-214748366,-2147483657,-2147483658,-2147483659。 //说明待会儿肯定小于-2147483648,肯定溢出,则输出0。注意:这时候最后一位还没加入,接下来开始加入.....
}
result *= 10;//此时 result = -2147483640
if (result < limit + digit) { //这里相当于 result-digit < limit,判断溢出;为了避免数字溢出导致代码无法执行,因此这样表达
return 0; //溢出
}
result -= digit; //经过上面一个if语句的判断,发现不会溢出,那么就将最后一位加入至result
}
} else {
return 0;
}
//如果是正数就返回-result(result一直是负数)
return negative ? result : -result;
}
int limit = -Integer.MAX_VALUE;
最后,反过头来看,之所以是在负数的范畴内判断溢出,应该主要是两个原因:
- 整数值的范畴,最小值的绝对值要比最大值的绝对值大1;
- 统一在负数范围内判断溢出,能够减少代码复杂度,否则就要写判断上溢出和下溢出的两段代码了;