LeetCode Everyday:坚持价值投资,做时间的朋友!!!
题目:
请你来实现一个 atoi 函数,使其能将字符串转换成整数。首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
- 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
- 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
- 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。在任何情况下,若函数不能进行有效的转换时,请返回 0 。
提示:
- 本题中的空白字符只包括空格字符
' '
。 - 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1] [−231,231−1], 如果数值超过这个范围,请返回INT_MAX ( 2 31 − 1 ) (2^{31}-1) (231−1)或INT_MIN ( − 2 31 ) (-2^{31}) (−231)
示例:
- 示例1
输入: "42" 输出: 42
- 示例2
输入: " -42" 输出: -42 解释: 第一个非空白字符为 '-', 它是一个负号。我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
- 示例3
输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
- 示例4
输入: "words and 987" 输出: 0 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。因此无法执行有效的转换。
- 示例5
输入: "-91283472332" 输出: -2147483648 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 因此返回 INT_MIN(-2^{31}) 。
代码
方法一: 常规判断
执行用时 :44 ms, 在所有 Python3 提交中击败了76.38%的用户
内存消耗 :13.7 MB, 在所有 Python3 提交中击败了7.14%的用户
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
str = str.lstrip() # lstrip() 方法用于截掉字符串左边的空格或指定字符
if len(str) == 0 or (str[0].isdigit()==False and str[0] not in ['-','+']):
return 0
res, i = str[0], 1
while i < len(str) and str[i].isdigit():
res += str[i]
i += 1
try:
res = int(res)
return min(max(res, -2**31), 2**31-1)
except:
return 0
"""
For Example: input: str = '4193 with words'
output: 4193
"""
str = '4193 with words'
solution = Solution()
result = solution.myAtoi(str)
print('输出为:', result) # 4193
方法二: 正则表达式
执行用时 :40 ms, 在所有 Python3 提交中击败了90.33%的用户
内存消耗 :13.7 MB, 在所有 Python3 提交中击败了7.14%的用户
import re
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: 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) #返回值
#return max(min(int(*re.findall('^[\+\-]?\d+', str.lstrip())), 2**31 - 1), -2**31)
"""
For Example: input: str = '4193 with words'
output: 4193
"""
str = '4193 with words'
solution = Solution()
result = solution.myAtoi(str)
print('输出为:', result) # 4193
题解的几点说明:
^
:匹配字符串开头[\+\-]
:代表一个+字符或-字符?
:前面一个字符可有可无\d
:一个数字+
:前面一个字符的一个或多个\D
:一个非数字字符*
:前面一个字符的0个或多个
补充
1.相关re知识点
-
第一组:
" * "
: 匹配前面的子表达式零次或多次" + "
: 匹配前面的子表达式一次或多次" ? "
: 匹配前面的子表达式零次或一次
-
第二组:
" [abc] "
:方括号表示字符集合,例子表示一个字符串有一个 “a” 或 “b” 或 “c” 等价于 [z|b|c]" [^abc] "
:^表示一个字符串中不应该出现某些模式,即匹配未包含该集合的任意字符- 下面几个个也常用
" [a-z] "
: 表示一个字符串中存在一个 a 和 z 之间的所有字母" [0-9] "
: 表示一个字符串中存在一个 0 和 9 之间的所有数字" [^a-z] "
:表示一个字符串中不应该出现 a 到 z 之间的任意一个字母
-
第三组:
" \d "
: 匹配一个数字字符,等价[0-9]" \D "
: 匹配一个非数字字符,等价[^0-9]" \w "
: 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”" \W "
: 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”
2.Pyhton re 模块的相关使用
-
🔶 re.match函数:尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.match(pattern, string, flags=0)
-
🔶 re.search方法:re.search 扫描整个字符串并返回第一个成功的匹配。
re.search(pattern, string, flags=0)
- 🔶对于返回的匹配的值,可以使用group(num)匹配对象函数来获取匹配表达式
import re
line = "We are the best."
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print ("matchObj.group() : ", matchObj.group())
print ("matchObj.group(1) : ", matchObj.group(1))
print ("matchObj.group(2) : ", matchObj.group(2))
else:
print ("No match!!")
输出: matchObj.group() : We are the best.
matchObj.group(1) : We
matchObj.group(2) : the
参考
- https://www.bilibili.com/video/BV1UZ4y1j7LS
- https://leetcode-cn.com/problems/string-to-integer-atoi/solution/python-1xing-zheng-ze-biao-da-shi-by-knifezhu/
- https://leetcode-cn.com/problems/string-to-integer-atoi/solution/xiong-mao-shua-ti-python3-yi-qi-xue-xi-zheng-ze-bi/