題目來源:https://leetcode-cn.com/problems/string-to-integer-atoipython
實現一個 atoi 函數,使其能將字符串轉換成整數。正則表達式
首先,該函數會根據須要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。segmentfault
當咱們尋找到的第一個非空字符爲正或者負號時,則將該符號與以後面儘量多的連續數字組合起來,做爲該整數的正負號;假如第一個非空字符是數字,則直接將其與以後連續的數字字符組合起來,造成整數。bash
該字符串除了有效的整數部分以後也可能會存在多餘的字符,這些字符能夠被忽略,它們對於函數不該該形成影響。微信
注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不須要進行轉換。函數
在任何狀況下,若函數不能進行有效的轉換時,請返回 0。spa
說明:.net
假設咱們的環境只能存儲 32 位大小的有符號整數,那麼其數值範圍爲 [−231, 231 − 1]。若是數值超過這個範圍,請返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。code
示例 1:blog
輸入: "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 (−231) 。
+
和 -
的狀況。定義 sign
,初始化爲 1
表示正數,如果遇到 -
則修改成 -1
,表示負數+
和 -
字符的狀況下,判斷第一個字符不爲數字直接跳出循環;其中越界這部分的內容能夠參考下面的文章:
上面的文章中大體說起了越界的狀況,這裏的處理大同小異。只是這裏遍歷的字符不一樣於負數取模,處理最小值邊界的狀況下要注意。
class Solution: def myAtoi(self, str: str) -> int: # max_value_div_10 = (1<<31) // 10 # min_value_div_10 = -(-((1<<31)-1) // -10) INT_MAX = (1<<31) - 1 INT_MIN = -(1<<31) str_len = len(str) # 去除空格,這裏不使用 lstrip() 避免產生新的遍歷 # 直接定位不爲空格的字符索引 index = 0 while index < str_len: if str[index] != ' ': break index += 1 # 若是索引值就等於字符長度,直接返回 0 if index == str_len: return 0 # 判斷取出空格後首位字符,判斷合法,記錄正負 sign = 1 first_chr = str[index] if first_chr == '+': index += 1 sign = 1 elif first_chr == '-': index += 1 sign = -1 res = 0 while index < str_len: cur_chr = str[index] if cur_chr > '9' or cur_chr < '0': break cur_chr = int(cur_chr) # 判斷是否越界 if res > INT_MAX // 10 or (res == INT_MAX // 10 and cur_chr > 7): return INT_MAX # 這裏處理邊界有些不一樣,與上面說起的文章比較,須要注意 if res < -(INT_MIN // -10) or (res == -(INT_MIN // -10) and cur_chr > 8): return INT_MIN # 每一步都把符號位乘進去 res = res * 10 + sign * cur_chr index += 1 return res
這裏說起一個比較騷的解法。除了導入必要庫,使用正則表達式一行代碼就解決了該問題。來源出自下面這位做者的題解:
大體是這樣的:
class Solution: def myAtoi(self, s: str) -> int: import re return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)
這裏 max(min(數字,2**31 - 1
), -2**31
) 處理邊界問題,re.findall() 這裏找的就是符合條件的部分,*
星號表達式在這裏表示解包。
雖然這樣的解法很是騷氣,也建議思考背後實現的原理。
以上就是本篇的主要內容
歡迎關注微信公衆號《書所集錄》