zoukankan      html  css  js  c++  java
  • Java String 转整形

    最近看剑指 Offer,最后的面试案例有一道字符串转整形的题,虽然题本身不难,但是需要考虑很多特殊情况,包括参数为空字符串、null 以及溢出等。

    好奇看了一下 Java 源码中 Integer 类的 parseInt() 方法的实现(valueOf() 方法调用了parseInt() 方法),发现这个实现对于溢出的处理很巧妙,故在此处记录一下。

    之前自己实现字符串转整形的方法时,用 long 来表示最后转换完的结果,然后再强转成 int 型,这样可以方便的处理溢出的情况。

    // 部分参考了 Integer.parseInt() 的实现
    static int strToInt(String str){
        if (str == null || str.length() == 0)
            throw new NumberFormatException(str);
        long res = 0;
        boolean negative = false;
        int len = str.length();
        int i = 0;
    
        char firstChar = str.charAt(0);
        if (firstChar < '0'){
            if (firstChar == '-'){
                negative = true;
            }else if (firstChar != '+'){
                throw new NumberFormatException(str);
            }
    
            if (len == 1){
                throw new NumberFormatException(str);
            }
            i++;
        }
    
        while(i < len){
            char ch = str.charAt(i);
            if (ch < '0' || ch > '9'){
                throw new NumberFormatException(str);
            }
    
            int digit = str.charAt(i++) - '0';
            res = res * 10 + digit;
    
            if (negative == false && res > Integer.MAX_VALUE){
                throw new NumberFormatException(str);
            }
            if (negative == true && res - 1 > Integer.MAX_VALUE){
                throw new NumberFormatException(str);
            }
        }
    
        return negative ? -(int)res : (int)res;
    }
    View Code

    然后看到了 Integer.parseInt() 的实现,每次进行乘操作和加(这里是减)操作之前,都会先判断一下最终结果的大小,如果有可能超出 int 的范围,就不会执行乘或减的运算。

    public static int parseInt(String s, int radix) throws NumberFormatException{
        // 省略异常情况的判断。。。
    
        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;
    }
    View Code

     LeetCode 上有一道转整形的题,允许更多的输入情况。顺便做了一下,代码如下(14 ms,38.6 M):

    public int myAtoi(String str) {
      if (str == null)
           return 0;
    
       long res = 0;
       boolean negative = false;
       int i = 0;
    
       str = str.trim();
    
       if (str.length() == 0){
           return 0;
       }
    
       int len = str.length();
    
       char firstChar = str.charAt(0);
    
           if (firstChar == '-'){
               negative = true;
               i++;
           }else if (firstChar == '+'){
               i++;
           }
    
       while(i < len){
           char ch = str.charAt(i);
           if (ch < '0' || ch > '9'){
               return negative ? -(int)res : (int)res;
           }
    
           int digit = str.charAt(i++) - '0';
           res = res * 10 + digit;
    
           if (negative == false && res > Integer.MAX_VALUE){
               return Integer.MAX_VALUE;
           }
           if (negative == true && res - 1 > Integer.MAX_VALUE){
               return Integer.MIN_VALUE;
           }
       }
    
       return negative ? -(int)res : (int)res;
    }
    View Code
  • 相关阅读:
    vue指令参考
    jquery easyui 研究(一)Datagrid初始化设置
    HTML之响应协议
    HTTP协议之请求协议
    HTTP协议之HTTP概述
    Day18_函数定义_形参_实参_可变参数
    Day19_名称空间和作用域_函数的嵌套_函数第一类对象的使用_闭包函数
    跳转语句 break 和 continue
    JS中强制类型转换
    toString
  • 原文地址:https://www.cnblogs.com/ainsliaea/p/10531805.html
Copyright © 2011-2022 走看看