[LeetCode] NO. 8 String to Integer (atoi)
[题目] Implement atoi to convert a string to an integer.
[题目解析] 该题目比较常见,从LeetCode上看代码通过率却只有13.7%,于是编码提交,反复修改了三四次才完全通过。该题目主要需要考虑各种测试用例的情况,比如"+5"、" 67"、" +0078"、" 12a56--"、int的最大值最小值溢出等情况,通过这个题目,联系到实际项目中,我们一定要多考虑边界情况,各种输入的情况,确保代码健壮性。
1 public int myAtoi(String str) { 2 if(null == str || 0 == str.length()) return 0; 3 str = str.trim(); //剔除无效字符 4 char first = str.charAt(0); 5 if(str.length() == 1 && !Character.isDigit(first)) return 0; //无效字符返回0,比如"+" 6 boolean isNeg = (first == '-'); //判断第一个字符是否为负号 7 int idx = isNeg ? 1 : 0; 8 if(first == '+') idx = 1; 9 while(str.charAt(idx) == '0'){ //把最前面的0去掉 10 idx++; 11 } 12 int result = 0; 13 while(idx < str.length()){ 14 char ch = str.charAt(idx); 15 if(!Character.isDigit(ch)) break; //如果遇到非数字字符,则终止循环,返回已经计算的数字 16 int num = ch - '0'; //char字符转化成对应数字 17 if(isNeg && result > Integer.MAX_VALUE/10) return Integer.MIN_VALUE; //检测整数是否溢出的情况 18 if(isNeg && result == Integer.MAX_VALUE/10 && num > 8) return Integer.MIN_VALUE; 19 if(!isNeg && result > Integer.MAX_VALUE/10) return Integer.MAX_VALUE; 20 if(!isNeg && result == Integer.MAX_VALUE/10 && num > 7) return Integer.MAX_VALUE; 21 result = result * 10 + num; 22 idx++; 23 } 24 return isNeg?(-result):result; 25 }
我们不妨来分析下java自带的string转化为int的方法,我们发现有Integer.valueOf()和Integer.parseInt()两个方法,我们进入方法去看。
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
我们发现这两个方法都调用了同一个方法parseInt(s,10),那么我们来分析这个方法就可以了。
public static int parseInt(String s, int radix) throws NumberFormatException { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */ if (s == null) { throw new NumberFormatException("null"); } if (radix < Character.MIN_RADIX) { //radix参数指定转化为几进制的数 throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0; boolean negative = false; int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { negative = true; //为负数 limit = Integer.MIN_VALUE; } else if (firstChar != '+') //如果第一个字符不是数字也不是‘+’、‘-’符号,则抛出格式异常 throw NumberFormatException.forInputString(s); if (len == 1) // Cannot have lone "+" or "-" throw NumberFormatException.forInputString(s); i++; } multmin = limit / radix; while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++),radix); //转化成对应数字 if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; } //计算出来是负数 } else { throw NumberFormatException.forInputString(s); } return negative ? result : -result; }