leetcode 8 思路及code(帶註釋)
阿新 • • 發佈:2021-01-30
技術標籤:leetcodepythonleetcodepython字串正則表示式
題目分析
以上是三種方法的提交結果,第一個為官方解答DFA,第二個為自己手寫的if-else,最後一個為正則匹配。
題目並不難,函式主要就是解決字串轉數字
- 自己想到的就是手寫,一輪迴圈,但是邊界需要做判斷
- 看題解有用正則表示式解決的,寫法比較簡答,效率也並不高
- 學過《形式語言與自動機》這門課,感覺也沒什麼用處,但是看官方題解,用到了DAF(確定的有限狀態自動機),有種學有所用的感覺
解題
- 方法一
- 解題思路
- 去掉開頭的空格字元
- 符號判斷,正負數,需要注意特殊情況 [+1 -> 1; ±1 -> 0]
- 迴圈找到數字邊界
- 轉為整數,輸出,注意題目邊界要求
- code
python3版本,主要利用了字串的切片操作
class Solution:
def myAtoi(self, s: str) -> int:
maxValue = 2 ** 31
i = 0
s = s.lstrip() # 去字串最左端空格
if s == '': # 異常處理空字串
return 0
# 處理符號
sign = 1
if s[0] == '-':
sign = -1
i = 1
if s[0] == '+':
i = 1
# 查詢字元中數字開頭結尾
start = i
while i < len(s) and '0' <= s[i] <= '9':
i += 1
if start == i:
return 0
x = sign * int(s[start:i])
if -maxValue <= x < maxValue:
return x
elif x < -maxValue:
return -maxValue
else:
return maxValue - 1
- 方法二
- 解題思路
- 正則表示式提取
- 符號判斷,正負數,需要注意特殊情況 [+1 -> 1; ±1 -> 0]
- 迴圈找到數字邊界
- 轉為整數,輸出,注意題目邊界要求
- code
python3版本,主要利用了字串的切片操作
class Solution2:
def myAtoi(self, s: str) -> int:
'''
1. s.lstrip() 刪除字串最左端空格字元
2. 正則表示式 ^[\+\-]?\d+, ^匹配字串開頭字元, [\+\-]?匹配0個或者一箇中括號中的字元,\d表示數字字元,+表示至少一個
3. re.findall返回列表, 前面的*是解包的意思,由於取第一個數字串,故列表中只有一個元素,解包即去掉列表轉為字串,但是這裡不能取
4. int(*re.findall),找到即返回數字,否則就是0
5. 處理越界,先與最大取最小值,在與最小值取最大值
:param s:
:return:
'''
return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2 ** 31 - 1), -2 ** 31)
- 方法三(具體圖見官方解答)
- 解題思路
- 狀態轉移圖
- 狀態轉移表
- 程式表示狀態轉移表
- code
python3版本,主要利用了字串的切片操作
class DFA:
def __init__(self):
'''
繪製狀態轉移表
state為當前狀態,初始為start
sign為正負號標記
ans為最終答案
state_table為狀態轉移表
'''
self.state = 'start'
self.sign = 1
self.ans = 0
self.state_table = {
'start': ['start', 'signed', 'in_num', 'end'],
'signed': ['end', 'end', 'in_num', 'end'],
'in_num': ['end', 'end', 'in_num', 'end'],
'end': ['end', 'end', 'end', 'end']
}
def get_col_state(self, char):
'''
對應每個列表下標
:param char:
:return:
'''
if char.isspace():
return 0
elif char == '-' or char == '+':
return 1
elif char.isdigit():
return 2
else:
return 3
def get_current_state(self, char):
'''
獲取當前狀態並更新狀態
獲取當前值,儲存符號狀態
:param char:
:return:
'''
self.state = self.state_table[self.state][self.get_col_state(char)]
if self.state == 'in_num':
self.ans = self.ans * 10 + int(char)
self.ans = min(self.ans, MAX_SIGNED) if self.sign == 1 else min(self.ans, -MIN_SIGNED)
if self.state == 'signed':
self.sign = -1 if char == '-' else 1
class Solution:
def myAtoi(self, s: str) -> int:
dfa = DFA()
for c in s:
dfa.get_current_state(c)
return dfa.sign * dfa.ans