美文网首页剑指offer
剑指offer(四十九)把字符串转换成整数

剑指offer(四十九)把字符串转换成整数

作者: 向前的zz | 来源:发表于2020-04-02 11:04 被阅读0次

    点击进入 牛客网题库:把字符串转换成整数

    题目描述

    将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0

    输入描述:
    输入一个字符串,包括数字字母符号,可以为空

    输出描述:
    如果是合法的数值表达则返回该数字,否则返回0

    示例1
    输入
    +2147483647
    1a33

    输出
    2147483647
    0

    上来我就撸了一个,花了大概32分钟左右,因为前面遇到过这个题目,不然可能还要更长时间

    不想看废话的直接看最后一个标题,中间内容是我一开始遇到这个题的思路和想法

    QQ图片20171201103504.gif

    方法一

    public int StrToInt(String str) {
            //为空的时候判断
            if (str == null || "".equals(str)) {
                return 0;
            }
            //int 最小值长度是11 -2147483647
            final int strLength = str.length();
            if (strLength > 11) {
                return 0;
            }
    
            int value = 0;
            final char firstChar = str.charAt(0);
            //是否带符号 + - 或着是否合法
            if (firstChar < '0') {
                if (firstChar == '-') {
                    value = Integer.MIN_VALUE;
                } else if (firstChar == '+') {
                    value = Integer.MAX_VALUE;
                } else {
                    //不合法
                    return 0;
                }
            }
    
            if (value == 0) { //没带符号
                //integer最大值10位,越界了
                if (strLength > 10) {
                    return 0;
                }
                //判断是否超过正数最大值
                if (strLength == 10) {
                    char[] cs = {'2', '1', '4', '7', '4', '8', '3', '6', '4', '7'};
                    for (int i = 0; i < strLength; i++) {
                        //其中有一个就不合法
                        if (str.charAt(i) - cs[i] > 0) {
                            return 0;
                        }
                    }
                }
    
                int tmp = 0;
                int pre = 1;
    
                for (int i = 0; i < strLength; i++) {
                    //其中有一个就不合法
                    int a = str.charAt(strLength - i - 1) - '0';
                    if (a > 9) {
                        return 0;
                    }
                    //倍速
                    tmp += a * pre;
                    pre *= 10;
                }
    
                return tmp;
    
            } else {
                if (value == Integer.MIN_VALUE) { //负数
                    //负数最大值判断
                    if (strLength == 11) {
                        char[] cs2 = {'2', '1', '4', '7', '4', '8', '3', '6', '4', '8'};
                        for (int i = 1; i < strLength; i++) {
                            //其中有一个就不合法
                            if (str.charAt(i) - cs2[i - 1] > 0) {
                                return 0;
                            }
                        }
                    }
    
                    int tmp = 0;
                    int pre = 1;
    
                    for (int i = 1; i < strLength; i++) {
                        //其中有一个就不合法
                        int a = str.charAt(strLength - i) - '0';
                        if (a > 9) {
                            return 0;
                        }
                        //倍速
                        tmp += a * pre;
                        pre *= 10;
                    }
    
                    //记得这里要加个负数符号
                    return -tmp;
                } else {
                    //正数最大值判断
                    if (strLength == 11) {
                        char[] cs = {'2', '1', '4', '7', '4', '8', '3', '6', '4', '7'};
                        for (int i = 1; i < strLength; i++) {
                            //其中有一个就不合法
                            if (str.charAt(i) - cs[i - 1] > 0) {
                                return 0;
                            }
                        }
                    }
    
                    int tmp = 0;
                    int pre = 1;
    
                    for (int i = 1; i < strLength; i++) {
                        //其中有一个就不合法
                        int a = str.charAt(strLength - i) - '0';
                        if (a > 9) {
                            return 0;
                        }
                        //倍速
                        tmp += a * pre;
                        pre *= 10;
                    }
    
                    return tmp;
                }
            }
        }
    

    上面代码我第一次写出来的时候,写出来的,提交了好几次,然后才通过的

    分析自己遇到的问题

    正负值的判断 顺便把第一个不合法的排除

    因为 ‘-’ ‘+’ 排再数字后面,准确来说是排在字符 ‘0’ 后面,这样就可以判断正与负了

    int value = 0;
    final char firstChar = str.charAt(0);
    //是否带符号 + - 或着是否合法
    if (firstChar < '0') {
        if (firstChar == '-') {
            value = Integer.MIN_VALUE;
        } else if (firstChar == '+') {
            value = Integer.MAX_VALUE;
        } else {
            //不合法
            return 0;
        }
    }
    

    点击查看 ->> 百度百科 ascii码表

    越界判断

    【正负判断,最大值和最小值,我这个方法比较low,就是每个字符进行了比较,然后出的结果】

    举个列子:当为负值的时候的判断,是否超出最大值

    if (strLength == 11) {
        char[] cs2 = {'2', '1', '4', '7', '4', '8', '3', '6', '4', '8'};
          for (int i = 1; i < strLength; i++) {
            //其中有一个就不合法
            if (str.charAt(i) - cs2[i - 1] > 0) {
                return 0;
            }
        }
    }                 
    

    中间出现字母

    int a = str.charAt(strLength - i) - '0';
    //关键代码
    if (a > 9) {
    return 0;
    }
    这个是关键代码,因为ascii码表中 字母比数字要大,这样进行判断

    点击查看 ->> 百度百科 ascii码表

    for (int i = 1; i < strLength; i++) {
        //其中有一个就不合法
        int a = str.charAt(strLength - i) - '0';
        //关键代码
        if (a > 9) {
            return 0;
        }
        //倍速
        tmp += a * pre;
        pre *= 10;
    }
    

    犯了个低级错误,负数没有加负号返回

     if (value == Integer.MIN_VALUE) { //负数
            ...       
            //记得这里要加个负数符号
           return -tmp;
    }
    

    以上就是我一开始做这个题目的一些问题。

    看到这里,恭喜你,看了上面的一大堆废话【算法的魅力啊】

    方法二 仅供参考

    public int StrToInt(String str) {
            if (str == null || "".equals(str)) {
                return 0;
            }
            final char[] a = str.toCharArray();
            int fuhao = 0;
            long sum = 0;
            for (int i = fuhao; i < a.length; i++) {
                //判断是不是负号
                if (a[i] == '-') {
                    fuhao = 1;
                    continue;
                }
    
                //判断是不是正号
                if (a[i] == '+') {
                    continue;
                }
    
                //不合法的情况下
                if (a[i] < '0' || a[i] > '9') {
                    return 0;
                }
                sum = sum * 10 + (a[i] - '0');
            }
            
            
            if (fuhao == 0) {
                if (sum > Integer.MAX_VALUE) {
                    return 0;
                }
                return (int) sum;
            } else {
                if (-sum < Integer.MIN_VALUE) {
                    return 0;
                }
                return (int) -sum;
            }
        }
    

    这个是不是很简单,哈哈


    QQ图片20171201103554.gif

    再来个jdk Integer.parseInt() 方法的代码

    public int StrToInt(String str) {
            if (str == null)
                return 0;
            int result = 0;
            boolean negative = false;//是否负数
            int i = 0, len = str.length();
            /**
             * limit 默认初始化为 负的 最大正整数 ,假如字符串表示的是正数
             * 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,
             * 判断是否溢出
             */
            int limit = -Integer.MAX_VALUE;
            int multmin;
            int digit;
     
            if (len > 0) {
                char firstChar = str.charAt(0);//首先看第一位
                if (firstChar < '0') { // Possible leading "+" or "-"
                    if (firstChar == '-') {
                        negative = true;
                        limit = Integer.MIN_VALUE;//在负号的情况下,判断溢出的值就变成了 整数的 最小负数了
                    } else if (firstChar != '+')//第一位不是数字和-只能是+
                        return 0;
                    if (len == 1) // Cannot have lone "+" or "-"
                        return 0;
                    i++;
                }
                //判断是否溢出
                //就是 result *= 10 的时候是否溢出了
                multmin = limit / 10;
                while (i < len) {
                    // Accumulating negatively avoids surprises near MAX_VALUE
                    digit = str.charAt(i++)-'0';//char转int
                    if (digit < 0 || digit > 9)//0到9以外的数字
                        return 0;
     
                    //判断溢出
                    if (result < multmin) {
                        return 0;
                    }
                    result *= 10;
                    if (result < limit + digit) {
                        return 0;
                    }
                    result -= digit;
                }
            } else {
                return 0;
            }
            //如果是正数就返回-result(result一直是负数)
            return negative ? result : -result;
        }
    
    

    相关文章

      网友评论

        本文标题:剑指offer(四十九)把字符串转换成整数

        本文链接:https://www.haomeiwen.com/subject/ynbtphtx.html