当前位置:网站首页>字符串转换整数 (atoi)

字符串转换整数 (atoi)

2022-08-09 12:00:00 爱敲代码的Harrison

题目

力扣链接:字符串转换整数 (atoi)

代码

package com.lt.tiq01;

/** * @author Harrison * @create 2022-06-26-11:20 * @motto 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。 */
public class P006_StringToIntegerAtoi {
    
    public int myAtoi(String s) {
    
        if(s==null || s.equals("")){
    
            return 0;
        }
        // trim()把字符串的空格去掉,一个系统函数
        s=removeHeadZero(s.trim());
        if(s==null || s.equals("")){
    
            return 0;
        }
        char[] str=s.toCharArray();
        if(!isValid(str)){
    
            return 0;
        }
        // str 是符合日常书写的,正经整数形式
        // 为什么一定要转成负数的形式接着?
        // -2147483648
        // 2147483647
        // 因为负数的绝对值比正数的绝对值大1,如果硬要拿正数接着
        // 那么字符串"2147483648"就没法转换了,但其实按要求应转换为系统最大2147483647
        // 因为是用负数的形式接着,所以不会溢出
        boolean posi=str[0]=='-'?false:true;
        int minq=Integer.MIN_VALUE/10;
        int minr=Integer.MIN_VALUE%10;
        int res=0;
        int cur=0;
        for(int i=(str[0]=='-' || str[0]=='+')?1:0; i<str.length; i++){
    
            cur='0'-str[i];
            if(res<minq || (res==minq && cur<minr)){
    
                // 正数溢出返回系统最大,负数溢出返回系统最小
                return posi?Integer.MAX_VALUE:Integer.MIN_VALUE;
            }
            res=res*10+cur;
        }
        // "-2147483648" -> -2147483648
        // "2147483647" -> 2147483647

        // res是用负数形式表达的
        // "2147483648" -> 2147483647
        // 下面if的情况,res是正数的形式,但却是系统最小,不会溢出,因为使用负数形式接着的
        // 这种情况下转成系统最大
        if(posi && res==Integer.MIN_VALUE){
    
            return Integer.MAX_VALUE;
        }
        return posi?-res:res;
    }

    public static String removeHeadZero(String str){
    
        boolean r=(str.startsWith("+") || str.startsWith("-"));
        // 如果原字符串第一个字符包含'+'或'-',那就从第二个字符开始找第一个不是'0'的字符
        int s=r?1:0;
        for(; s<str.length(); s++){
    
            if(str.charAt(s)!=0){
    // 找到第一个不是字符'0'的位置
                break;
            }
        }
        // s 到了第一个不是'0'字符的位置
        int e=-1;
        // 左<-右(从右往左找第一个不是数字字符的位置)
        for(int i=str.length()-1; i>=(r?1:0); i--){
    
            if(str.charAt(i)<'0' || str.charAt(i)>'9'){
    
                e=i;
            }
        }
        // e 到了最左的 不是数字字符的位置
        // substring(s,e) 左闭右开[s,e)
        // 如果e==-1,说明s后面都是数字字符
        // 再加上第一个字符'+'或者'-',如果有的话
        return (r?String.valueOf(str.charAt(0)):"")+str.substring(s,e==-1?str.length():e);
    }

    // isValid() 检查是否是有效的整数
    public static boolean isValid(char[] chas){
    
        if(chas[0]!='-' && chas[0]!='+' && (chas[0]<'0' || chas[0]>'9')){
    
            return false;
        }
        if((chas[0]=='-' || chas[0]=='+') && chas.length==1){
    
            return false;
        }
        // 上面两个if没中,只剩下三张情况
        // 0 +... -... num
        // 0位置字符是'+',后面是数字字符
        // 0位置字符是'-',后面是数字字符
        // 0位置就是数字字符,后面也是
        // 然后接着从1位置开始检查,如果中间有任何不是数字字符,直接return false
        for(int i=1; i<chas.length; i++){
    
            if(chas[i]<'0' || chas[i]>'9'){
    
                return false;
            }
        }
        // 经过上面的层层过滤,剩下的字符串一定是符合我们日常书写的,正经的整数形式
        return true;
    }
}

原网站

版权声明
本文为[爱敲代码的Harrison]所创,转载请带上原文链接,感谢
https://harrison-lhs.blog.csdn.net/article/details/125468359