前往
大廳
主題

LeetCode - 8. String to Integer (atoi) 解題心得

Not In My Back Yard | 2021-04-24 00:00:01 | 巴幣 0 | 人氣 397

題目連結:


題目意譯:
實作函式 myAtoi(string s),其將一字串轉為一個 32 位元有號整數(類似於 C/C++ 之函式 atoi())

myAtoi(string s) 之演算法如下:
讀入並忽略所以前導白空白字元;
檢查下一個字元(如果還不是字串結尾的話)是否為 '-' 或是 '+'。如果是其中一種則將其讀入。而這決定了最終結果是負或是正。如果沒有出現則預設為正;
讀入字元直到非數字字元出現或是碰到字串結尾,並忽略字串剩餘部分。
將讀入的數字們轉為一個整數(即 "123" → 123 、 "0032" → 32)。如果沒有數字被讀入,則轉換的整數為 0。如果有必要,則轉換正負號(步驟二);
如果整數超出 32 位元有號整數之範圍 [-2 ^ 31, 2 ^ 31 - 1],則鉗定(Clamped)該數使其落於範圍中。更精確地說,小於 -2 ^ 31 之整數應鉗定成 -2 ^ 31,而大於 2 ^ 31 - 1 之整數應鉗定為 2 ^ 31 - 1。
回傳整數作為最終結果。

注:
只有空白字元 ' ' 被視為白空白字元。
不要忽略任何除了前導白空白以外的字元或者是數字後的剩餘字串。

限制:
0 ≦ s.length ≦ 200
s 包含英文字母(小寫和大寫)、數字(0 ~ 9)、 ' ' 、 '+' 、 '-' 以及 '.'。



範例測資:
範例 1:
輸入: s = "42"
輸出: 42
解釋: 標以底線之字元為被讀入的字元,插入符號('^')代表著目前讀取位置。
步驟 1: "42"(沒有字元讀入,因為沒有前導白空白字元)
         ^
步驟 2: "42"(沒有字元讀入,因為不是 '-' 或是 '+')
         ^
步驟 3: "42"("42" 被讀入)
           ^
剖析之整數為 42。
因為 42 位於 [-2 ^ 31, 2 ^ 31 - 1] 中,所以最終結果為 42。

範例 2:
輸入: s = "   -42"
輸出: -42
解釋:
步驟 1: "   -42"(前導白空白被讀入並忽略)
            ^
步驟 2: "   -42"('-' 被讀入,所以結果應為負數)
             ^
步驟 3: "   -42"("42" 被讀入)
               ^
剖析之整數為 -42。
因為 -42 位於 [-2 ^ 31, 2 ^ 31 - 1] 中,所以最終結果為 -42。

範例 3:
輸入: s = "4193 with words"
輸出: 4193
解釋:
步驟 1: "4193 with words"(沒有字元讀入,因為沒有前導白空白字元)
         ^
步驟 2: "4193 with words"(沒有字元讀入,因為不是 '-' 或是 '+')
         ^
步驟 3: "4193 with words"("4193" 被讀入;讀取停止,因為下一個字元並非數字)
             ^
剖析之整數為 4193。
因為 4193 位於 [-2 ^ 31, 2 ^ 31 - 1] 中,所以最終結果為 4193。

範例 4:
輸入: s = "words and 987"
輸出: 0
解釋:
步驟 1: "words and 987"(沒有字元讀入,因為沒有前導白空白字元)
         ^
步驟 2: "words and 987"(沒有字元讀入,因為不是 '-' 或是 '+')
         ^
步驟 3: "words and 987"(讀取立即停止,因為該字元為一非數字字元 'w')
         ^
剖析之整數為 0,因為沒有數字被讀入。
因為 0 位於 [-2 ^ 31, 2 ^ 31 - 1] 中,所以最終結果為 0。

範例 5:
輸入: s = "-91283472332"
輸出: -2147483648
解釋:
步驟 1: "-91283472332"(沒有字元讀入,因為沒有前導白空白字元)
         ^
步驟 2: "-91283472332"('-' 被讀入,所以結果應為負數)
          ^
步驟 3: "-91283472332"("91283472332" 被讀入)
                     ^
剖析之整數為 -91283472332。
因為 -91283472332 小於範圍 [-2 ^ 31, 2 ^ 31 - 1] 之下界,所以最終結果被鉗定為 -2 ^ 31 = -2147483648。


解題思維:
就是單純地模擬並實作題目給定的演算法(過程),其大致如下:
讀掉前面的白空白 →
讀入 '-' 、 '+' ,如果有的話 →
讀入數字直到碰到不是數字的字元 →
將讀入的數字轉成整數 →
判斷整數有沒有在範圍裡,沒有就鉗定進範圍內 →
回傳整數
上述過程中,時時刻刻都要同時判斷當前是否抵達字串的結尾。

而過程中比較麻煩的是鉗定的部分。因為數字可能可以很長(字串長度可以到 200 個字元),所以直接轉換可能會得到一個很大的整數。對於 C++ 可能無法存在於 64 位元有號整數裡。

因此在轉換的時候,一旦數字之值超過 2147483647 或是 -2147483648 就不再繼續轉換並且將數字限制為 2147483647 或 -2147483648 即可做到鉗定。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

相關創作

更多創作