第八題:字符串轉(zhuǎn)換整數(shù) (atoi)
請你來實現(xiàn)一個 atoi 函數(shù),使其能將字符串轉(zhuǎn)換成整數(shù)。
首先,該函數(shù)會根據(jù)需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符為止。接下來的轉(zhuǎn)化規(guī)則如下:
如果第一個非空字符為正或者負(fù)號時,則將該符號與之后面盡可能多的連續(xù)數(shù)字字符組合起來,形成一個有符號整數(shù)。
假如第一個非空字符是數(shù)字,則直接將其與之后連續(xù)的數(shù)字字符組合起來,形成一個整數(shù)。
該字符串在有效的整數(shù)部分之后也可能會存在多余的字符,那么這些字符可以被忽略,它們對函數(shù)不應(yīng)該造成影響。
注意:假如該字符串中的第一個非空格字符不是一個有效整數(shù)字符、字符串為空或字符串僅包含空白字符時,則你的函數(shù)不需要進(jìn)行轉(zhuǎn)換,即無法進(jìn)行有效轉(zhuǎn)換。
在任何情況下,若函數(shù)不能進(jìn)行有效的轉(zhuǎn)換時,請返回 0 。
提示:
本題中的空白字符只包括空格字符 ' ' 。
假設(shè)我們的環(huán)境只能存儲 32 位大小的有符號整數(shù),那么其數(shù)值范圍為 [?231, 231 ? 1]。如果數(shù)值超過這個范圍,請返回 INT_MAX (231 ? 1) 或 INT_MIN (?231) 。
示例 1:
輸入: "42"
輸出: 42
示例 2:
輸入: " -42"
輸出: -42
解釋: 第一個非空白字符為 '-', 它是一個負(fù)號。
我們盡可能將負(fù)號與后面所有連續(xù)出現(xiàn)的數(shù)字組合起來,最后得到 -42 。
示例 3:
輸入: "4193 with words"
輸出: 4193
解釋: 轉(zhuǎn)換截止于數(shù)字 '3' ,因為它的下一個字符不為數(shù)字。
示例 4:
輸入: "words and 987"
輸出: 0
解釋: 第一個非空字符是 'w', 但它不是數(shù)字或正、負(fù)號。
因此無法執(zhí)行有效的轉(zhuǎn)換。
示例 5:
輸入: "-91283472332"
輸出: -2147483648
解釋: 數(shù)字 "-91283472332" 超過 32 位有符號整數(shù)范圍。
因此返回 INT_MIN (?231) 。
V1版本
這個題的示例真多,這個題的示例真多,題理清楚了就好解決,總得來說還是逐個字符解析
1.前面有空格,跳過繼續(xù)向下解析
2.前面有字母,不繼續(xù)向下解析
3.正號/負(fù)號/數(shù)字后面如果不是數(shù)字,不繼續(xù)向下解析
代碼如下
public int myAtoi(String str) {
// 最終結(jié)果
int result = 0;
// 是否為正數(shù)
boolean isPositive = true;
// 是否退出
boolean isExit = false;
// 臨時變量保存數(shù)字
int digit;
for (int i = 0; i < str.length(); i++) {
// 遇到數(shù)字處理數(shù)字,提前判斷是否越出整數(shù)范圍
if (Character.isDigit(str.charAt(i))) {
digit = str.charAt(i) - 48;
// 檢查是否會越界
if (isPositive && (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 7))) {
return Integer.MAX_VALUE;
}
if (!isPositive && (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && digit > 8))) {
return Integer.MIN_VALUE;
}
result = result * 10 + digit;
isExit = true;
continue;
}
// 跳出循環(huán)
if (isExit) {
break;
}
// 是否為空格,跳出當(dāng)前循環(huán)
if (Character.isSpaceChar(str.charAt(i))) {
continue;
}
// 遇到 + 號,后續(xù)如果不是遇到連續(xù)的數(shù)字則退出
if (str.charAt(i) + 0 == 43) {
if (isExit) {
return 0;
}
isExit = true;
continue;
}
// 遇到 - 號,后續(xù)如果不是遇到連續(xù)的數(shù)字則退出,同時更新符號位
if (str.charAt(i) + 0 == 45) {
if (isExit) {
return 0;
}
isExit = true;
isPositive = false;
continue;
}
// 遇到其它符號跳出循環(huán)
break;
}
return isPositive?result : -result;
}

這個題解決倒是不難,去看看官方有什么好的解決思路學(xué)習(xí)一下
V2版本
官方的描述還是比較好,直接轉(zhuǎn)過來
方法一:自動機
思路
字符串處理的題目往往涉及復(fù)雜的流程以及條件情況,如果直接上手寫程序,一不小心就會寫出極其臃腫的代碼。因此,為了有條理地分析每個輸入字符的處理方法,我們可以使用自動機這個概念:
我們的程序在每個時刻有一個狀態(tài) s,每次從序列中輸入一個字符 c,并根據(jù)字符 c 轉(zhuǎn)移到下一個狀態(tài) s'。這樣,我們只需要建立一個覆蓋所有情況的從 s 與 c 映射到 s' 的表格即可解決題目中的問題。
但實現(xiàn)方式也是if 一大堆的判斷,算了下一題