# 02-字符串转换整数 (atoi)

LeetCode原题


请你来实现一个 atoi 函数,使其能将字符串转换成整数。


 示例 1:
 输入: "42"
 输出: 42

 示例 2:
 输入: "   -42"
 输出: -42
 解释: 第一个非空白字符为 '-', 它是一个负号。
 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

 示例 3:
 输入: "4193 with words"
 输出: 4193
 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

 示例 4:
 输入: "words and 987"
 输出: 0
 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
 因此无法执行有效的转换。
 示例 5:
 输入: "-91283472332"
 输出: -2147483648
 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
 因此返回 INT_MIN (−231) 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 方法三:最优解,耗时1秒
    public static int myAtoi3(String str){
        int len = str.length();
        //去除前导空格
        int index=0;
        while(index<len){
            if(str.charAt(index)!=' '){
                break;
            }
            index++;
        }
        System.out.println("第一个非空字符下标:"+index);
        if(index==len) {
            return 0;
        }
        // 第1个字符如果是符号,判断合法性,并记录正负
        int sign = 1;
        char firstChar = str.charAt(index);
        if(firstChar == '+'){
            index++;
            sign=1;
        }else if(firstChar =='-'){
            index++;
            sign=-1;
        }

        //不能使用long类型,long类型也能越界
        int res =0;
        while(index<len){
            char currChar = str.charAt(index);
            //判断合法性
            if(currChar>'9' || currChar<'0'){
                break;
            }

            //题目中说:环境只能存储32位大小的有符号整数,
            //因此,需要提前判断乘以10以后是否越界
            if(res>Integer.MAX_VALUE/10 ||
                    (res==Integer.MAX_VALUE/10 && (currChar-'0')>Integer.MAX_VALUE%10)){
                return Integer.MAX_VALUE;
            }
            if(res<Integer.MIN_VALUE/10 ||
                    (res==Integer.MIN_VALUE/10 && (currChar-'0')>-(Integer.MIN_VALUE%10))){
                return Integer.MIN_VALUE;
            }
            //每一步都把符号位乘进去
            res=res*10+sign*(currChar-'0');
            index++;

        }

        return res;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 方法二:正则,耗时18秒
    public static int myAtoi2(String str){
        /*
        正则表达式规则:
        1,以 + 或 - 或 数字开头,出现0或1次
        2,\d表示数字,出现1次或多次
        3,只需判断开头 ^表示开头
         */
        str=str.trim();
        String regex ="^[\\+\\-]?\\d+";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        int num=0;
        //find() 尝试查找与该模式匹配的输入序列的下一个子序列。
        if(m.find()) {
            String strNum = m.group();
            try{
                num = Integer.parseInt(strNum);
            }catch (Exception e){
                //数字太大,去int的最大值或最小值
                if(strNum.charAt(0)=='-'){
                    num=Integer.MIN_VALUE;
                }else{
                    num=Integer.MAX_VALUE;
                }

            }
        }
        return num;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 // 方法一 普通:耗时10秒
    public static  int myAtoi(String str) {
        long num=0;
        str=str.trim();
        if(("").equals(str) || "-".equals(str)||"+".equals(str)) return 0;
        char[] chArr =str.toCharArray();
        // - 的ASCII为45
        // - 45 , 0 48 , 9 57
        if(chArr[0]==45 || chArr[0]==43){
            for(int i=1;i<chArr.length;i++){
                if(!(chArr[1] >=48 && chArr[1]<=57)){
                    return 0;
                }
                if(chArr[i] >=48 && chArr[i]<=57){

                }else{
                    str=chArr[0]+str.substring(1,i);
                    break;
                }
            }
            try{
                num=Long.valueOf(str);
            }catch(Exception e){
                if(str.startsWith("-")){
                    num=Integer.MIN_VALUE;
                }else{
                    num=Integer.MAX_VALUE;
                }
            }
        }else if (chArr[0] >=48 && chArr[0]<=57){
            for(int i=0;i<chArr.length;i++){
                if(chArr[i] >=48 && chArr[i]<=57){

                }else{
                    str=str.substring(0,i);
                    break;
                }
            }
            try{
                num=Long.valueOf(str);
            }catch(Exception e){
                num=Integer.MAX_VALUE;
            }

        }else{
            num=0;
        }
        if(num>Integer.MAX_VALUE ){
            num=Integer.MAX_VALUE;
        }else if(num<Integer.MIN_VALUE){
            num=Integer.MIN_VALUE;
        }
        return (int)num;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54