1 问题
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:
1.若干空格
2.(可选)一个符号字符(‘+’ 或 ‘-’)
3. 数字,字母,符号,空格组成的字符串表达式
4. 若干空格
转换算法如下:
- 去掉无用的前导空格
- 第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
- 判断整数的有效部分:
3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
3.3 整数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −2^31 ,大于 2^31 − 1 的整数应该被调整为 2^31 − 1 - 去掉无用的后导空格
数据范围:
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)
- 状态机
字符串无非就是这些类型:[ ’ ‘(空格), 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