[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; 
    }

  

posted @ 2016-08-25 21:46  三刀  阅读(154)  评论(0编辑  收藏  举报