天天看點

8. 字元串轉換整數 (atoi)

請你來實作一個 

atoi

 函數,使其能将字元串轉換成整數。

首先,該函數會根據需要丢棄無用的開頭空格字元,直到尋找到第一個非空格的字元為止。接下來的轉化規則如下:

  • 如果第一個非空字元為正或者負号時,則将該符号與之後面盡可能多的連續數字字元組合起來,形成一個有符号整數。
  • 假如第一個非空字元是數字,則直接将其與之後連續的數字字元組合起來,形成一個整數。
  • 該字元串在有效的整數部分之後也可能會存在多餘的字元,那麼這些字元可以被忽略,它們對函數不應該造成影響。

注意:假如該字元串中的第一個非空格字元不是一個有效整數字元、字元串為空或字元串僅包含空白字元時,則你的函數不需要進行轉換,即無法進行有效轉換。

在任何情況下,若函數不能進行有效的轉換時,請傳回 0 。

提示:

  • 本題中的空白字元隻包括空格字元 

    ' '

     。
  • 假設我們的環境隻能存儲 32 位大小的有符号整數,那麼其數值範圍為 [−231,  231 − 1]。如果數值超過這個範圍,請傳回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

輸入: "42"
輸出: 42
      

示例 2:

輸入: "   -42"
輸出: -42
解釋: 第一個非空白字元為 '-', 它是一個負号。
     我們盡可能将負号與後面所有連續出現的數字組合起來,最後得到 -42 。
      

示例 3:

輸入: "4193 with words"
輸出: 4193
解釋: 轉換截止于數字 '3' ,因為它的下一個字元不為數字。
      
輸入: "words and 987"
輸出: 0
解釋: 第一個非空字元是 'w', 但它不是數字或正、負号。
     是以無法執行有效的轉換。      
輸入: "-91283472332"
輸出: -2147483648
解釋: 數字 "-91283472332" 超過 32 位有符号整數範圍。 
     是以傳回 INT_MIN (−231) 。


      
class Solution:
    def myAtoi(self, str: str) -> int:
        if not str:return 0
        res=''
        s=str.lstrip()
        for i in range(len(s)):
            if s[i].isalpha() or s[i]==' ' or s[i]=='.':break
            if i>0 and not s[i].isdigit():break
            if s[i].isdigit():
                res+=s[i]
            
        if not res:return 0
        if s[0]=='-':
            if not s[1].isdigit():
                return 0
            res='-'+res
        if s[0]=='+' and not s[1].isdigit():
            return 0
        
        res=int(res)
        if res>=2147483648:
            return 2147483647
        elif res<=-2147483648:
            return -2147483648
        else:
            return res 
             
MAX=2**31-1
MIN=-2**31
class Auto:
    def __init__(self):
        self.state='start'
        self.sign=1
        self.ans=0
        self.table = {
            'start': ['start', 'signed', 'in_number', 'end'],
            'signed': ['end', 'end', 'in_number', 'end'],
            'in_number': ['end', 'end', 'in_number', 'end'],
            'end': ['end', 'end', 'end', 'end'],
        }

    def get_col(self,c):
        if c.isspace():
            return 0
        if c=='+' or c=='-':
            return 1
        if c.isdigit():
            return 2
        return 3

    def 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,MAX) if self.sign==1 else min(self.ans,-MIN)
        elif self.state=='signed':
            self.sign=1 if c=='+' else -1

class Solution:
    def myAtoi(self, str: str) -> int:
        auto=Auto()
        for c in str:
            auto.get(c)
        return auto.sign*auto.ans