8. 字符串转换整数 (atoi) 耗时2ms

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

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

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

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

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

示例 4:
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
 因此无法执行有效的转换。

示例 5:
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
 因此返回 INT_MIN (−231) 。

来源:力扣(LeetCode)
题目在这类鸭

思路:

  1. 将字符串为空或者字符串内部都是空格的情况,返回为0;
  2. 获得有效部分,将字符串前后的空格进行消除,利用trim()函数,获得有效部分,然后获取第一个位置的字符,第一个字符是符号位,我用sign来表示结果的正负,如果是数字的话,那么此数为正,sign记为1,如果是‘-’,那么符号为负,sgin记为-1,其他则均为不合法的字符将其返回为0,所以要将存储数字的变量res,初始化为0。
  3. 做好符号处理了,开始遍历字符串,注意题目要求的是在字符串中连续的数字,比如234www123,其实我们返回的数字234,并不是234123,那么提供我们又一个便利,当我们在遍历的过程中遇到字母的时候,就可以直接退出循环返回结果。
  4. 因为本题要求只能储存32位的整形,因为你在处理字符串,相加得到数字的时候(res=res*10+pop),可能出现溢出的情况,所以我们要做出处理。

为了理解的直观,res=res*10+pop分成两句写,且认为res为正数

temp=res*10+pop;
res=temp;
  1. 如果temp越界,那么temp>Integer.MAX_VALUE,则res>=Integer.MAX_VALUE/10(注意这里有个‘/’,具有取整的性质)
  2. 如果res>Integer.MAX_VALUE/10,那么一定temp>Integer.MAX_VALUE。
  3. 如果res=Integer.MAX_VALUE,那么当pop>Integer.MAX_VALUE%10,即大于Integer.MAX_VALUE的个位数,则越界。

代码

扫描二维码关注公众号,回复: 9888233 查看本文章
class Solution {
        public int myAtoi(String str) {
        //如果字符串为空,则直接返回零
        if(str==null) return 0;
        //使字符串前后的空格字符都消失
        str = str.trim();
        //如果字符串的长度此时为0,它之前内部都是空格
        if ( str.length() == 0)
            return 0;
        //此时判断此数的符号问题,要使此数字有意义,第一位必须是'-'或数字
        char firstChar = str.charAt(0);
        //默认符号位是正数
        int sign = 1;
        //记录字符开始遍历的开始位置
        int start = 0;
        //保存从字符串中提取的数字
        int res = 0;
        //判断首位的符号
        if (firstChar == '+') {
            sign = 1;
            start++;
        } else if (firstChar == '-') {
            sign = -1;
            start++;
        }
        //开始遍历剩余的字符串
        for (int i = start; i < str.length(); i++) {
            //当遇到的字符不为数字时,直接返回
            //此时已经将首位是字母的情况考虑了,因为res的默认值为0
            //当首位遇到字母或者其他非数字的时候,res*sign=0 
            if (str.charAt(i)>'9'||str.charAt(i)<'0') {
                return (int) res * sign;
            }
            //得到的数字
            int pop = str.charAt(i) - '0';
            //因为题目要求是32位,可能会溢出 需要做出相应处理 ,遇到溢出的情况直接返回最大或者最小,注意符号问题
            if(sign==1) {
            	if (res > Integer.MAX_VALUE/10 || (res == Integer.MAX_VALUE / 10 && pop > 7)) return Integer.MAX_VALUE;
            }
            if(sign==-1) {
            	if (-res < Integer.MIN_VALUE/10 || (-res == Integer.MIN_VALUE / 10 && -pop < -8)) return Integer.MIN_VALUE;
            }
            //无溢出风险的时候,进行相加
            res = res * 10 + pop;
        }
        return res * sign;
    }
}
发布了9 篇原创文章 · 获赞 1 · 访问量 300

猜你喜欢

转载自blog.csdn.net/ShangDiYeGuJi/article/details/104659103