一、题设
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:
读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
二、基本思路
1.切片法:找出符号位,找出第一个不间断数的开端,结尾,再利用python的切片直接截取。不过这一方法需要附加的其他的判断就很多了,这一方法也是我开始用的,卡了4个小时还有很多案例没通过。
2.正则表达式+re:这一方法是在题目评论区看到的,但是正则我还不咋会哈哈哈,暂时先码一下。具体参见兔飞小朋友写的文章:python正则表达式:re库的使用_兔飞小朋友的博客-CSDN博客_python re库
3.一遍过法:从头开始就分析可能出现的情况,可能性,直接进行判断合法、删空格、处理符号位、组数、判断溢出等问题,过完一遍即可 。
三、代码实现
一、正则:
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) #返回值
二、一遍过:
class Solution(object):
def myAtoi(self, s):
index = 0 #当前下标
lens = len(s) #字符串长度
# 去掉前面的空格
for index in range(lens):
if not s[index] == ' ':
break
# 如果全是空格
if index == lens:
return 0
# 符号位,默认为+
sign = 1
firstsign = s[index]
if firstsign == '+':
index += 1
if firstsign == '-':
sign = -1
index += 1
# res存储结果
res = 0
while index < lens:
current_char = s[index]
# 不合法的情况
if current_char < '0' or current_char > '9':
break
# 组数
res = res * 10 + int(current_char)
index += 1
# 判断数值有无溢出
if res * sign < - pow(2,31):
return - pow(2,31)
if res * sign > pow(2,31) - 1:
return pow(2,31) - 1
return res*sign
四、效率总结
图1:正则效率
图2:一遍过效率
这题我具体来说是做了12个小时,记录第一次奔溃。以上两者效率其实大差不差,正则的时间复杂度会更高一些,但是代码量是很少的。我第一种方法做不出完全是因为题目对于特殊输出没有啥规定,也没指出来具体的案例,全程就是按照案例去摸索什么时候输出0啊什么的,所谓面向用例编程。我觉得这题纯纯的恶心人,价值确实不是很大,做这题主要是在特殊情况的判断上折了马腿了。很烦很烦很烦,不过没关系,要继续加油哦,明天见~