題目鏈接
LeetCode 字符串轉換整數(atoi)[1]
題目描述
請你來實現一個 atoi
函數,使其能將字符串轉換成整數。
首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。接下來的轉化規則如下:
- 如果第一個非空字符爲正或者負號時,則將該符號與之後面儘可能多的連續數字字符組合起來,形成一個有符號整數。
- 假如第一個非空字符是數字,則直接將其與之後連續的數字字符組合起來,形成一個整數。
- 該字符串在有效的整數部分之後也可能會存在多餘的字符,那麼這些字符可以被忽略,它們對函數不應該造成影響。
注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不需要進行轉換,即無法進行有效轉換。
在任何情況下,若函數不能進行有效的轉換時,請返回 0
。
說明:
- 本題中的空白字符只包括空格字符 ' ' 。
- 假設我們的環境只能存儲
32
位大小的有符號整數,那麼其數值範圍爲 。如果數值超過這個範圍,請返回INT_MAX
() 或INT_MIN
() 。
示例1
輸入:
"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) 。
題解
官方題解用的有限狀態自動機,理解起來也是比較輕鬆的,寫起來也避免了一堆臃腫的 if-else
。但是我這裏就不用自動機了,直接模擬就行了,寫起來也很輕鬆好理解!
- 首先用一個變量
idx
標記當前遍歷到的位置,用sign = 1, -1
表示整數的正負性。 - 然後從
idx = 0
開始,將開頭的空格全部去掉。 - 然後判斷當前的位置
idx
處的字符是不是+, -
或者數字,並且idx
要小於字符串長度。如果一個都沒滿足,那麼說明是非法字符串,直接返回0
。 - 然後如果當前的位置
idx
處的字符是-
,那麼就令sign = -1
。否則如果是+
,就令sign = 1
。然後遍歷後一個字符。 - 最後遍歷一段連續的數字,把它轉換成整數,注意轉換的時候要乘上符號位
sign
。如果發現數字超過了[INT_MIN, INT_MAX]
範圍,就直接返回最大最小值就行了。 - 否則的話最後就是合法整數,直接返回答案。
代碼
c++
class Solution {
public:
int myAtoi(string str) {
int idx = 0, n = str.size();
long res = 0, sign = 1;
while (idx < n && str[idx] == ' ') idx++;
if (idx >= n || (str[idx] != '+' && str[idx] != '-' && !isdigit(str[idx]))) return 0;
if (str[idx] == '-') {
sign = -1;
idx++;
} else if (str[idx] == '+') {
idx++;
}
while (idx < n && isdigit(str[idx])) {
res = res*10+sign*(str[idx++]-'0');
if (res > INT_MAX) return INT_MAX;
if (res < INT_MIN) return INT_MIN;
}
return res;
}
};
python
class Solution:
def myAtoi(self, str: str) -> int:
str = str.lstrip()
n, idx = len(str), 0
res, sign = 0, 1
if idx >= n or (str[idx] != '+' and str[idx] != '-' and not str[idx].isdigit()): return 0
if str[idx] == '-':
sign = -1
idx += 1
elif str[idx] == '+':
idx += 1
for c in str[idx:]:
if not c.isdigit(): break
res = res*10+sign*(int(c))
if res > 2**31-1: return 2**31-1
if res < -2**31: return -2**31
return res
正則表達式(python)
class Solution:
def myAtoi(self, str: str) -> int:
return max(min(int(*re.findall('^[\+\-]?\d+', str.lstrip())), 2**31-1), -2**31)
參考資料
[1]
LeetCode 字符串轉換整數(atoi): https://leetcode-cn.com/problems/string-to-integer-atoi/