引言
我们刚写完32位整数转化成英文表示和汉字表示,其中需要考虑Integer.MIN_VALUE的溢出情况,我们要做的这道题,更好的诠释了对这种情况的处理.
分析
在开始操作之前,我们要对这个字符串进行判断,看当前的字符串是否是合法的,具体的判定过程如下:
public static boolean isValid(char[] chas) {
if (chas[0] != '-' && (chas[0] < '0' || chas[0] > '9')) {
return false;
}
if (chas[0] == '-' && (chas.length == 1 || chas[1] == '0')) {
return false;
}
if (chas[0] == '0' && chas.length > 1) {
return false;
}
for (int i = 1; i < chas.length; i++) {
if (chas[i] < '0' || chas[i] > '9') {
return false;
}
}
return true;
}
逻辑非常简单,先判断第一位,然后在判断后面的几位,经过了合法性的判断.然后就开始转化了.我们在这里统一先变成负数,然后最后在判断是正还是负,先看代码,然后在分析
public static int convert(String str) {
if (str == null || str.equals("")) {
return 0; // can not convert
}
char[] chas = str.toCharArray();
if (!isValid(chas)) {
return 0; // can not convert
}
boolean posi = chas[0] == '-' ? false : true;
int minq = Integer.MIN_VALUE / 10;
int minr = Integer.MIN_VALUE % 10;
int res = 0;
int cur = 0;
for (int i = posi ? 0 : 1; i < chas.length; i++) {
cur = '0' - chas[i];
if ((res < minq) || (res == minq && cur < minr)) {
return 0; // can not convert
}
res = res * 10 + cur;
}
if (posi && res == Integer.MIN_VALUE) {
return 0; // can not convert
}
return posi ? -res : res;
}
其中困扰我们的就是 int minq = Integer.MIN_VALUE / 10;
int minr = Integer.MIN_VALUE % 10;这一段代码,然后就是
if ((res < minq) || (res == minq && cur < minr)) {
return 0; // can not convert
}
我们来解释一下,这代码的意思,我们首先知道,我们统一把值变成负值进行判断,因为Integer.MAX_VALUE和Integer.MIN_VALUE的关系,我们统一按照Integer.MIN_VALUE处理,那么如何判断溢出的情况呢,我们截取书中的内容:
这就是这个代码最重要的地方.因为如果它已经溢出了,就没法去判断了,所以我们要在他溢出之前进行判断,而在没有溢出的时候,就是两种情况一定会溢出,就是上述截图所说的.
我们加深印象,将核心代码在写一遍
for(int i=0;i<arr.length;i++)
{
cur = '0'-arr[i];//全部是负数
if(res<minq||(res==minq&&cur<minr))
{ return 0; }
res=res*10+cur;
}