【LeetCode】008——字符串转换整数(atoi)

在这里插入图片描述
在这里插入图片描述

解题思路

  本题第一反应就是顺序遍历字符串的每一个字符,然后根据题目要求进行判断,显然本题的难点就不在于算法本身,而在于对于各种情况和边界的考虑:

(1)如何去除开头空格字符;

  • 可以通过顺序遍历字符串字符,判断是否为空字符,如果是跳过该字符到下一个字符,直到第一个非空字符即可

(2)如何定位并标记符号位字符;

  • 定义一个变量flag,第一个非空字符为 '+' 标记为 1 ,为 '-' 标记为 -1

(3)如何截取连续数字字符;

  • 通过顺序遍历,判断是否为数字字符 '0'-'9'

(4)如何将连续数字字符串转为整数;

  • 该数字字符-'0'就是该数字字符对应的数值,例如: '7'-'0'=7
  • 那如果是一串连续的数字字符组成的字符串呢,如:"123",此时,没法用上面的方法直接得到,可以如下:
  • 设置一个base=0,顺序遍历 “123”
  • 当遍历到'1' 时,base = base * 10 + '1' - '0',得到base = 1
  • 当遍历到'2' 时,base = base * 10 + '2' - '0' = 1 * 10 + 2,得到base = 12
  • 当遍历到'3' 时,base = base * 10 + '3' - '0' = 12 * 10 + 33,得到base = 123
  • 遍历结束,得到结果为:123
  • 然后再根据符号位标记,得到最终结果,与符号位相乘

(5)如何判断越界;

  • 数值范围为 [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [231,2311]。如果数值超过这个范围,返回 I N T _ M A X ( 2 31 − 1 ) INT\_MAX (2^{31} − 1) INT_MAX(2311) I N T _ M I N ( − 2 31 ) INT\_MIN (−2^{31}) INT_MIN(231)
  • 实现时用Integer.valueOf()函数抛出的异常来判断整数越界

(6)如何考虑程序的完整性;

  • 第一个非空字符既不是正号或负号,也不是数字,返回0;
  • 字符串为空,或者字符串内只包含空字符,返回0;
  • 第一个非空字符是正号或负号,但接下来的第二个字符不是数字,返回0;

对于"+-2"、"+ 2"这两种情况,都返回0

Java代码

class Solution {
    public int myAtoi(String str) {
        //如果字符串为null或长度小于1,返回0
        if(str == null || str.length() < 1) return 0;
        
        int idx = 0; //索引
        //去除开头空格
        while(idx < str.length() && str.charAt(idx) == ' '){
            idx++;
        }
        
        int flag = 1;  //标记正负
        int base = 0;  //数值
        //标记符号位
        if(idx < str.length() && (str.charAt(idx) == '+' || str.charAt(idx) == '-')){
            flag = (str.charAt(idx) == '+') ? 1 : -1;
            idx++;
        }
        //截取数值及越界判断
        while(idx < str.length() && str.charAt(idx) >= '0' && str.charAt(idx) <= '9'){
            //Integer.MAX_VALUE=2147483647
            //Integer.MIN_VALUE=-2147483648
            
            //越界判断
            //base > Integer.MAX_VALUE / 10时,base * 10 就会越界
            //base == Integer.MAX_VALUE / 10 = 214748364,base * 10 = 2147483640,最后一个数就不能大于7
            if (base > Integer.MAX_VALUE / 10 || (base == Integer.MAX_VALUE / 10 && str.charAt(idx) - '0' > 7)) {  
                return (flag == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;  
            }  
            // 计算转换值  
            base = 10 * base + (str.charAt(idx++) - '0');
        }
        return base * flag;
    }
}

Python3代码

class Solution:
    def myAtoi(self, str: str) -> int:
        str = str.lstrip() # 去除开头的空格
        
        if str == '': # 为空
            return 0
        
        idx = 0
        flag = 1
        ret = '0'
        
        if idx < len(str) and (str[idx] == '+' or str[idx] == '-'):
            flag = 1 if (str[idx] == '+') else -1
            idx += 1
        
        
        while(idx < len(str) and str[idx].isdigit()):
            ret += str[idx]
            idx += 1
        
        
        result = int(ret) * flag
        if result > 2147483647:
            return 2147483647
        elif result < -2147483648:
            return -2147483648
        else:
            return result

C++代码

class Solution {
public:
    int myAtoi(string str) {
        int i = 0;
        while(' ' == str[i]) i++;// 去掉空格
        int flag = 1;
        
        if(i < str.size() && (str[i] == '+' || str[i] == '-')){
            flag = (str[i] == '+') ? 1 : -1;
            i++;
        }
        
        int base = 0;        
        while(i < str.size() && str[i] >= '0' && str[i] <= '9'){
            if ((base > INT_MAX / 10) || (base == INT_MAX / 10 && (str[i] - '0') > 7)) {  
                return (flag == 1) ? INT_MAX : INT_MIN;  
            }
            
            base = base * 10 + (str[i] - '0');
            i++;
        }
        
        return base * flag;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值