【算法面试宝典】字符串转换整数 - LeetCode8

1 算法描述

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ' ' 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
 

示例 1:

输入:s = "42"
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:"42"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"42"(读入 "42")
           ^
解析得到整数 42 。
由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:

输入:s = "   -42"
输出:-42
解释:
第 1 步:"   -42"(读入前导空格,但忽视掉)
            ^
第 2 步:"   -42"(读入 '-' 字符,所以结果应该是负数)
             ^
第 3 步:"   -42"(读入 "42")
               ^
解析得到整数 -42 。
由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:

输入:s = "4193 with words"
输出:4193
解释:
第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止)
             ^
解析得到整数 4193 。
由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
示例 4:

输入:s = "words and 987"
输出:0
解释:
第 1 步:"words and 987"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"words and 987"(当前没有读入字符,因为这里不存在 '-' 或者 '+')
         ^
第 3 步:"words and 987"(由于当前字符 'w' 不是一个数字,所以读入停止)
         ^
解析得到整数 0 ,因为没有读入任何数字。
由于 0 在范围 [-231, 231 - 1] 内,最终结果为 0 。
示例 5:

输入:s = "-91283472332"
输出:-2147483648
解释:
第 1 步:"-91283472332"(当前没有读入字符,因为没有前导空格)
         ^
第 2 步:"-91283472332"(读入 '-' 字符,所以结果应该是负数)
          ^
第 3 步:"-91283472332"(读入 "91283472332")
                     ^
解析得到整数 -91283472332 。
由于 -91283472332 小于范围 [-231, 231 - 1] 的下界,最终结果被截断为 -231 = -2147483648 。
 

提示:

0 <= s.length <= 200
s 由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/string-to-integer-atoi
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2 解题思路

字符串转换整数可以分三步来处理:
第一步:去除前置空格;

第二步:处理符号位;符号的处理可以使用 +1和-1来处理,正数不用处理,负数就乘以-1。

第三步:从左向右遍历字符;遍历的过程中要进行几个判断:

1)判断是否为数字,如果不是数字就跳出遍历;

2)判断是否超出最大值和最小值,超出的按照题目要求返回对应的值。

最大值和最小值计算公式:

假设 num 是最终的值,tmp 是遍历得到的值,max是int型最大值,min是int型最小值。那么有公式:

min <= num*10 + tmp <= max

转换得到:min/10 - tmp/10 <= num <= max/10 - tmp/10

计算机的除法是没有余数的,所以可以简化为:min/10 <= num <= max/10 

可以分为两种情况 大于 和 等于。以num>=min/10为例,

如果num<min/10,肯定是会溢出的。但是如果num=min/10 = -2147483648/10 = -214748364。

如果tmp 的值小于-8,还是会溢出,所以小于最小值的判断条件为:

num<(min/10) || (num==min/10 && tmp<min%10)

大于最大值的判断条件为:

num>(max/10) || (num==min/10 && tmp>max%10)

编码如下所示:

   public int myAtoi(String s) {
        char[] chs = s.toCharArray();//字符串转化为字符数组
        int idx = 0;//字符串数组下标
        int sign = 1;//正负标识
        int num = 0;//目标数值

        //第一步:去除空格
        while(idx<chs.length && chs[idx]==' '){
            idx++;
        }
        //如果全是空格返回0
        if(idx>=chs.length){
            return 0;
        }

        //第二步:正负处理
        if(chs[idx] == '-'){
            sign = -1;
            idx++;
        } else if(chs[idx] == '+'){
            idx++;
        }

        //第三步:遍历字符数组
        while(idx<chs.length){
            if(chs[idx]>='0' && chs[idx]<='9'){//判断是否为数值
                int tmp = Character.getNumericValue(chs[idx])*sign;//字符转化为带符号的数值
                if((num<Integer.MIN_VALUE/10) || (num==Integer.MIN_VALUE/10 && tmp<Integer.MIN_VALUE%10)){//小于最小值处理
                    num = Integer.MIN_VALUE;
                    break;
                } else if((num>Integer.MAX_VALUE/10) || (num==Integer.MAX_VALUE/10 && tmp>Integer.MAX_VALUE%10)){//大于最大值处理
                    num = Integer.MAX_VALUE;
                    break;
                } else{
                    num = num*10 + tmp;
                }
                idx++;
            } else{
                break;
            }
        }
        return num;
    }

猜你喜欢

转载自blog.csdn.net/u010482601/article/details/121992693
今日推荐