8. 字符串转换整数 (atoi)
题目:将字符串中出现的第一个数字转换为整数输出(不太准确,具体看链接)
链接 https://leetcode.cn/problems/string-to-integer-atoi/
个人思路
- 开始觉得挺简单的,先用strip去掉空格,然后判断是否有正负号,接下来读取数字就好。
class Solution:
def myAtoi(self, s: str) -> int:
s = s.strip()
ans = ''
if s[0] in ['-','+']:
ans = ans + s[0]
s = s[1:]
for i in s:
# 判断是否为数字
if i.isdigit():
ans = ans + i
else:
return int(ans)
# 判断是否在范围内
if int(ans) > -2**31 and int(ans) < 2**31 - 1:
continue
else:
return int(ans[0:len(ans)-1])
return int(ans)
用例"words and 987"出现错误,因为int(“”)不能将空字符转为0
- 第二次理解错了题意,必须要数字出现在前面才算,否则返回0,即"abc 321"应该返回0。
class Solution:
def myAtoi(self, s: str) -> int:
s = s.strip()
ans = ''
if s[0] in ['-','+']:
ans = ans + s[0]
s = s[1:]
# 判断第一位是否为数字,否则转化为第一位为数字
if not s[0].isdigit():
for index in range(0,len(s)):
if s[index].isdigit():
s = s[index:]
break
for i in s:
# 判断是否为数字
if i.isdigit():
ans = ans + i
else:
if len(ans) == 0:
return 0
else:
return int(ans)
# 判断是否在范围内
if int(ans) > -2**31 and int(ans) < 2**31 - 1:
continue
else:
return int(ans[0:len(ans)-1])
return int(ans)
- 加几个if进行判断就好,总的来说不难,就是需要判断的情况有点多
class Solution:
def myAtoi(self, s: str) -> int:
s = s.strip()
ans = ''
if len(s) == 0:
return 0
if s[0] in ['-','+']:
ans = ans + s[0]
s = s[1:]
# 判断截取后长度为否为0
if len(s) == 0:
return 0
# 判断第一位是否为数字
if not s[0].isdigit():
return 0
for i in s:
# 判断是否为数字
if i.isdigit():
ans = ans + i
else:
return int(ans)
# 判断是否在范围内
if int(ans) > -2**31 and int(ans) < 2**31 - 1:
continue
else:
return -2**31 if int(ans) <= -2**31 else 2**31 - 1
return int(ans)
其他思路
- 官方:自动机
自动机(状态机):我们的程序在每个时刻有一个状态 s,每次从序列中输入一个字符 c,并根据字符 c 转移到下一个状态 s’。这样,我们只需要建立一个覆盖所有情况的从 s 与 c 映射到 s’ 的表格即可解决题目中的问题。
INT_MAX = 2 ** 31 - 1
INT_MIN = -2 ** 31
class Automaton:
def __init__(self):
self.state = 'start'
self.sign = 1
self.ans = 0
self.table = {
'start': ['start', 'signed', 'in_number', 'end'],
'signed': ['end', 'end', 'in_number', 'end'],
'in_number': ['end', 'end', 'in_number', 'end'],
'end': ['end', 'end', 'end', 'end'],
}
def get_col(self, c):
if c.isspace():
return 0
if c == '+' or c == '-':
return 1
if c.isdigit():
return 2
return 3
def get(self, c):
self.state = self.table[self.state][self.get_col(c)]
if self.state == 'in_number':
self.ans = self.ans * 10 + int(c)
self.ans = min(self.ans, INT_MAX) if self.sign == 1 else min(self.ans, -INT_MIN)
elif self.state == 'signed':
self.sign = 1 if c == '+' else -1
class Solution:
def myAtoi(self, str: str) -> int:
automaton = Automaton()
for c in str:
automaton.get(c)
return automaton.sign * automaton.ans
复杂度分析
时间复杂度:O(n),其中 n 为字符串的长度。我们只需要依次处理所有的字符,处理每个字符需要的时间为 O(1)。
空间复杂度:O(1)。自动机的状态只需要常数空间存储。
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/string-to-integer-atoi/solution/zi-fu-chuan-zhuan-huan-zheng-shu-atoi-by-leetcode-/
- 正则表达式
class Solution:
def myAtoi(self, s: str) -> int:
return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
^:匹配字符串开头
[\+\-]:代表一个+字符或-字符
?:前面一个字符可有可无
\d:一个数字
+:前面一个字符的一个或多个
\D:一个非数字字符
*:前面一个字符的0个或多个
import re
class Solution:
def myAtoi(self, str: str) -> int:
INT_MAX = 2147483647
INT_MIN = -2147483648
str = str.lstrip() #清除左边多余的空格
num_re = re.compile(r'^[\+\-]?\d+') #设置正则规则
num = num_re.findall(str) #查找匹配的内容
num = int(*num) #由于返回的是个列表,解包并且转换成整数
return max(min(num,INT_MAX),INT_MIN) #返回值
作者:QQqun902025048
链接:https://leetcode.cn/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/