题目链接:力扣
解题思路:字符串处理,主要解决两个个问题:溢出问题,什么时候停止转换
对于溢出问题:无论是正数溢出还是负数溢出,都可以使用一个简单的方式进行判定,使用result保存转换后的结果,则result更新过程为:result=result*10+str[i]-'0',使用一个额外的变量prev表示上一轮result的值,如果本轮循环result/10的值不等于prev则发生的溢出,这种方式对于正数溢出和负数溢出的判断都适用。如果一个数乘10后发生了溢出,那么显然溢出后的值与原来的值不是10倍的关系。比如int a = 9876544321,则a*10 = 1286608618,1286608618/10 =128660861,不等于a 显然发生了溢出。
什么时候停止转换:
- 当已经读到数字时,如果下一个字符不是数字,则停止转换,可以使用一个额外的变量end=false,当读到数字时,更新end=true。如果下一个字符不是数字字符,并且end=true时,停止转换。
- 否则,也就是end=false时,即使读到的字符不是数字,也不能停止,此时可能是前导空格或者正负号
- 如果当前字符是空字符(无用的前导空格),continue
- 如果当前字符是+或-,使用一个变量flag保存符号,使end=true使end=true是为了防止连续两个符号位的干扰,比如+-123,转换的结果应该位0,
- 如果当前字符是数字字符,开始转换,并使end=true,以便在下一轮循环开始时,判断是否停止转换(end=true&&不是数字字符)
- 否则,break:这种情况一直没有读到数字,end一直等于false,也就是测试数据直接以字母开头,这种情况也直接停止转换
AC代码
class Solution {
public static int myAtoi(String s) {
char[] str = s.toCharArray();
int result = 0;
int flag = 1;
int prev = result;
boolean end = false;
for (char c : str) {
if (end && (c < '0' || c > '9')) {
break;
} else if (c == ' ') {
continue;
} else if (c == '+') {
end = true;
} else if (c == '-') {
flag = -flag;
end = true;
} else if (c >= '0' && c <= '9') {
prev = result;
result = result * 10 + c - '0';
if (result / 10 != prev) {
if (flag < 0) {
return Integer.MIN_VALUE;
} else {
return Integer.MAX_VALUE;
}
}
end = true;
}else {
break;
}
}
return flag * result;
}
}