【剑指offer】JZ67 把字符串转换成整数(atoi)

1 问题

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:
1.若干空格
2.(可选)一个符号字符(‘+’ 或 ‘-’)
3. 数字,字母,符号,空格组成的字符串表达式
4. 若干空格

转换算法如下:

  1. 去掉无用的前导空格
  2. 第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
  3. 判断整数的有效部分:
    3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
    3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
    3.3 整数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −2^31 ,大于 2^31 − 1 的整数应该被调整为 2^31 − 1
  4. 去掉无用的后导空格

数据范围:
1.0 <=字符串长度<= 100
2.字符串由英文字母(大写和小写)、数字(0-9)、’ ‘、’+‘、’-’ 和 ‘.’ 组成

示例1
输入:“82”
返回值:82

示例2
输入:" -12 "
返回值:-12
说明:去掉前后的空格,为-12

示例3
输入:“4396 clearlove”
返回值:4396
说明:6后面的字符不属于有效的整数部分,去除,但是返回前面提取的有效部分

示例4
输入:“clearlove 4396”
返回值:0

示例5
输入:“-987654321111”
返回值:-2147483648

2 答案

自己写的,主要是判断,感觉用for可能更简单一些,因为每轮都要i+=1

class Solution:
    def StrToInt(self , s: str) -> int:
        i = 0
        res_s = ''
        fushu = False
        shuzi = False
        ls = ['0','1','2','3','4','5','6','7','8','9']
        while i < len(s):
            if shuzi:
                if s[i] in ls:
                    res_s += s[i]
                    i += 1
                else:
                    break
            else:
                if s[i] == ' ':
                    i += 1
                elif s[i] == '+':
                    shuzi = True
                    i += 1
                elif s[i] == '-':
                    shuzi = True
                    fushu = True
                    i += 1
                elif s[i] in ls:
                    res_s += s[i]
                    shuzi = True
                    i += 1
                else:
                    break
        if res_s == '':
            return 0
        else:
            res = int(res_s)
        if fushu:
            res = -res
        if res > 2 ** 31 -1:
            res = 2 ** 31 -1
        if res < -2 ** 31:
            res = -2 ** 31
        return res

在这里插入图片描述

官方解

既然是将字符串转化为数字,那我们可以遍历字符串,一个字符串,一个字符地检查,然后取出掉无用的,取出数字,利用如下代码,一个数字一个数字地转换,前面的扩大十倍加上后面一位。

  • step 1:遍历字符串,用index记录全程的下标。
  • step 2:首先要排除空串,然后越过前导空格,以及前导空格后什么都没有就返回0.
  • step 3:然后检查符号,没有符号默认为正数。
  • step 4:再在后续遍历的时候,将数字字符转换成字符,遇到非数字则结束转换。
  • step 5:与Int型最大最小值比较,检查越界情况。
class Solution:
    def StrToInt(self , s: str) -> int:
        res = 0
        index = 0
        s = s.strip()
        n = len(s)
        if s == '':
            return 0
        sign = 1
        if s[index] == '+':
            index += 1
        elif s[index] == '-':
            index += 1
            sign = -1
        if index == n:
            return 0
        while index < n:
            c = s[index]
            if c < '0' or c > '9':
                break
            res = res*10+sign*(int(c)-int('0'))
            index += 1
        return min(max(res, -2**31), 2**31-1)
  1. 状态机

字符串无非就是这些类型:[ ’ ‘(空格), 0(前导或者数字中间的), [1-9], 其它非法字符,’-/+’ ],我们可以将其映射成数字: [0,1,2,3,4],一共有4种状态 0,1,2,3, 其中3退出状态机且返回当前保存的结果。

  • step 1:利用常数矩阵保存状态机。
  • step 2:遍历字符串,根据当前的字符类型,进入相应的状态。
  • step 3:数字状态要进行转换,并判断是否超过int型上下界。

在这里插入图片描述

class Solution:
    def StrToInt(self, s: str) -> int:
        states = [[0, 1, 2, 3, 1], [3, 1, 2, 3, 3], [3, 2, 2, 3, 3]]  # 第三种状态退出,所示直接没写,状态可以很好的和图对应,states[0]列表对应图中状态0
        res = 0
        top = 2 ** 31 - 1
        bottom = -(2 ** 31)
        n = len(s)
        sign = 1
        state = 0
        for i in range(n):
            c = s[i]
            if c == ' ':
                state = states[state][0]
            elif c == '0':
                state = states[state][1]
            elif c >= '1' and c <= '9':
                state = states[state][2]
            elif c == '-' or c == '+':
                state = states[state][4]
                if state == 1:
                    sign = -1 if c == '-' else 1
                else:
                    break
            else:
                state = states[state][3]
            if state == 2:
                res = res*10 + int(c) - int('0')
                res = min(res, top) if (sign == 1) else min(res, -bottom)
            if state == 3:
                break
        return sign * res

https://www.nowcoder.com/share/jump/9318638301700722502434

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouHerGetUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值