LeetCode 0008 字串轉整數

2021-10-17 18:51:04 字數 4179 閱讀 2809

請你來實現乙個 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:

輸入:str =

"42"

輸出:42

解釋:加粗的字串為已經讀入的字元,插入符號是當前讀取的字元。

第 1 步:"42"(當前沒有讀入字元,因為沒有前導空格)

^第 2 步:"42"(當前沒有讀入字元,因為這裡不存在 '-' 或者 '+')

^第 3 步:"42"(讀入 "42")

^解析得到整數 42 。

由於 "42" 在範圍 [-231, 231 - 1] 內,最終結果為 42 。

示例 2:

輸入:str =

" -42"

輸出:-42

解釋:第 1 步:" -42"(讀入前導空格,但忽視掉)

^第 2 步:" -42"(讀入 '-' 字元,所以結果應該是負數)

^第 3 步:" -42"(讀入 "42")

^解析得到整數 -42 。

由於 "-42" 在範圍 [-231, 231 - 1] 內,最終結果為 -42 。

示例 3:

輸入:str =

"4193 with words"

輸出:4193

解釋:第 1 步:"4193 with words"(當前沒有讀入字元,因為沒有前導空格)

^第 2 步:"4193 with words"(當前沒有讀入字元,因為這裡不存在 '-' 或者 '+')

^第 3 步:"4193 with words"(讀入 "4193";由於下乙個字元不是乙個數字,所以讀入停止)

^解析得到整數 4193 。

由於 "4193" 在範圍 [-231, 231 - 1] 內,最終結果為 4193 。

示例 4:

輸入:str =

"words and 987"

輸出:0

解釋:第 1 步:"words and 987"(當前沒有讀入字元,因為沒有前導空格)

^第 2 步:"words and 987"(當前沒有讀入字元,因為這裡不存在 '-' 或者 '+')

^第 3 步:"words and 987"(由於當前字元 'w' 不是乙個數字,所以讀入停止)

^解析得到整數 0 ,因為沒有讀入任何數字。

由於 0 在範圍 [-231, 231 - 1] 內,最終結果為 0 。

示例 5:

輸入:str =

"-91283472332"

輸出:-2147483648

解釋:第 1 步:"-91283472332"(當前沒有讀入字元,因為沒有前導空格)

^第 2 步:"-91283472332"(讀入 '-' 字元,所以結果應該是負數)

^第 3 步:"-91283472332"(讀入 "91283472332")

^解析得到整數 -91283472332 。

由於 -91283472332 小於範圍 [-231, 231 - 1] 的下界,最終結果被截斷為 -231 = -2147483648 。

1>源**

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)

2>演算法介紹

剛拿到這個題目的時候,我想到了之前編譯原理課上講過的正規表示式,正則表達對這種亂七八糟的輸入非常有效果,往往可以高效率的提取出我們需要的資訊。在題目中給出的例子裡,給出了多種匹配情況,於是我們可以根據題意來構造正規表示式。

'^[\+\-]?\d+'
含義為:

1.以』+『或』-『起始,其中』+'可以省略;

2.緊接著為數字符號,數字可以出現一次到多次

利用正規表示式解題的思路就是這樣,當然還有一些細節需要注意,比如空格處理、空字串處理等。

完成了題目之後思考了一下,這道題還有另一種解法,和編譯原理這門課也有點相似,那就是設計自動機來完成。

int_max =2**

31-1int_min =-2

**31

class

automaton

:def

__init__

(self)

: self.state =

'start'

self.sign =

1 self.ans =

0 self.table =

defget_col

(self, c)

:if c.isspace():

return

0if c ==

'+'or c ==

'-':

return

1if c.isdigit():

return

2return

3def

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 ==

1else

min(self.ans,

-int_min)

elif self.state ==

'signed'

: self.sign =

1if 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

以上是leetcode官方給出的**,這個**最有意思的部分就是,他用python的字典結構直接儲存了自動機,然後需要做的就只是按照自動機的邏輯進行遍歷字串即可。總體來說,雖然沒有正則表達方法簡潔,但也是十分優雅的。

字串 leetcode 43 字串相乘

給定兩個以字串形式表示的非負整數 num1 和 num2,返回 num1 和 num2 的乘積,它們的乘積也表示為字串形式。示例 1 輸入 num1 2 num2 3 輸出 6 示例 2 輸入 num1 123 num2 456 輸出 56088 說明 num1 和 num2 的長度小於110。nu...

棧 字串 leetcode394 字串解碼

題目 解題思路 遍歷字串,如果遇到的是數,則把數存入num 如果遇到的是左括號,那麼將num壓入數棧,將左括號前面的字串ans壓入字串棧,然後將num清0,將ans也清空 如果遇到的是右括號,那麼將數棧的棧頂數彈出記為 k,然後將當前的ans重複k次,連線到字串棧的棧頂字串後面,然後將字串棧的棧頂字...

LeetCode43 字串相乘

給定兩個以字串形式表示的非負整數num1和num2,返回num1和num2的乘積,它們的乘積也表示為字串形式。示例 1 輸入 num1 2 num2 3 輸出 6 示例 2 輸入 num1 123 num2 456 輸出 56088 題目分析 如果兩個字串中有乙個為0,則結果是0 否則的話,將其中乙...