leecode刷題(16)-- 字符串轉(zhuǎn)換整數(shù)
字符串轉(zhuǎn)換整數(shù)
描述:
請你來實(shí)現(xiàn)一個(gè) atoi
函數(shù)团甲,使其能將字符串轉(zhuǎn)換成整數(shù)天揖。
首先童叠,該函數(shù)會(huì)根據(jù)需要丟棄無用的開頭空格字符脂信,直到尋找到第一個(gè)非空格的字符為止佣渴。
當(dāng)我們尋找到的第一個(gè)非空字符為正或者負(fù)號(hào)時(shí)齿坷,則將該符號(hào)與之后面盡可能多的連續(xù)數(shù)字組合起來憔鬼,作為該整數(shù)的正負(fù)號(hào);假如第一個(gè)非空字符是數(shù)字胃夏,則直接將其與之后連續(xù)的數(shù)字字符組合起來轴或,形成整數(shù)。
該字符串除了有效的整數(shù)部分之后也可能會(huì)存在多余的字符仰禀,這些字符可以被忽略照雁,它們對于函數(shù)不應(yīng)該造成影響。
注意:假如該字符串中的第一個(gè)非空格字符不是一個(gè)有效整數(shù)字符答恶、字符串為空或字符串僅包含空白字符時(shí)饺蚊,則你的函數(shù)不需要進(jìn)行轉(zhuǎn)換。
在任何情況下悬嗓,若函數(shù)不能進(jìn)行有效的轉(zhuǎn)換時(shí)污呼,請返回 0。
說明:
假設(shè)我們的環(huán)境只能存儲(chǔ) 32 位大小的有符號(hào)整數(shù)包竹,那么其數(shù)值范圍為 [?231, 231 ? 1]燕酷。如果數(shù)值超過這個(gè)范圍籍凝,請返回 INT_MAX (2^31 ? 1) 或 INT_MIN (?2^31) 。
示例 1:
輸入: "42"
輸出: 42
示例 2:
輸入: " -42"
輸出: -42
解釋: 第一個(gè)非空白字符為 '-', 它是一個(gè)負(fù)號(hào)苗缩。
我們盡可能將負(fù)號(hào)與后面所有連續(xù)出現(xiàn)的數(shù)字組合起來饵蒂,最后得到 -42 。
示例 3:
輸入: "4193 with words"
輸出: 4193
解釋: 轉(zhuǎn)換截止于數(shù)字 '3' 酱讶,因?yàn)樗南乱粋€(gè)字符不為數(shù)字退盯。
示例 4:
輸入: "words and 987"
輸出: 0
解釋: 第一個(gè)非空字符是 'w', 但它不是數(shù)字或正、負(fù)號(hào)泻肯。
因此無法執(zhí)行有效的轉(zhuǎn)換渊迁。
示例 5:
輸入: "-91283472332"
輸出: -2147483648
解釋: 數(shù)字 "-91283472332" 超過 32 位有符號(hào)整數(shù)范圍。
因此返回 INT_MIN (?231) 灶挟。
思路:
這道題其實(shí)就是多個(gè)條件判斷:
- 判斷字符串開頭是否是空格字符琉朽;
- 判斷是否存在除了
-
和+
的非數(shù)字字符; - 如果有正負(fù)的話執(zhí)行正負(fù)判斷
- 判斷數(shù)值是否發(fā)生溢出膏萧。
當(dāng)我們執(zhí)行了這些判斷后漓骚,只需要定義一個(gè)初始值 base = 0蝌衔,定義數(shù)組下標(biāo) i榛泛,從前往后遍歷,將遍歷到的符合條件的字符依次排序噩斟,便能將字符串轉(zhuǎn)換為整數(shù)了曹锨。
代碼如下:
class Solution {
public int myAtoi(String str) {
if(str == null || str.length() == 0) {
return 0;
}
//正負(fù)號(hào)判斷,轉(zhuǎn)換值剃允,索引位數(shù)
int sign = 1, base = 0, i = 0;
//剔除開始空白字符
while(i < str.length() && str.charAt(i) == ' '){
i++;
}
//判斷正負(fù)號(hào)
if(i < str.length() && (str.charAt(i) == '-' || str.charAt(i) == '+')){
sign = str.charAt(i++) == '-' ? -1 : 1;
}
//索引有效數(shù)字字符
while(i < str.length() && str.charAt(i) >= '0' && str.charAt(i) <= '9'){
if(base > Integer.MAX_VALUE / 10 || (base == Integer.MAX_VALUE / 10 && str.charAt(i) - '0' > 7)){
return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
//計(jì)算轉(zhuǎn)換值
base = 10 * base + (str.charAt(i++) - '0');
}
//計(jì)算結(jié)果值
return base * sign;
}
}
解釋:
這里我們需要在每個(gè)判斷語句中加入 i < str.length()
沛简,不然通不過 Leecode 提交。
然后代碼中的單引號(hào)不能換成雙引號(hào)斥废,意義不一樣椒楣,單引號(hào)引的數(shù)據(jù)是 char 類型,雙引號(hào)引的數(shù)據(jù)是 string 類型牡肉。
然后可以看到代碼中有base = 10 * base + (str.charAt(i++) - '0');
這樣的捧灰,其中的 -
代表ascii轉(zhuǎn)換,將字符轉(zhuǎn)換為數(shù)字统锤。
最后我們看一下數(shù)值溢出這塊毛俏,其實(shí)我在之前的博文中有寫:leecode刷題(12)-- 整數(shù)反轉(zhuǎn)。
假設(shè) base為正數(shù)饲窿,如果 base = 10 * base + (str.charAt(i++) - '0') 發(fā)生溢出煌寇,那么一定有 base >= INT_MAX / 10 。
同樣的逾雄,當(dāng) base為負(fù)數(shù)時(shí)阀溶,rev <= INT_MIN / 10 會(huì)發(fā)生溢出腻脏。
同時(shí)我們需要注意 (str.charAt(i++) - '0') 的數(shù)值,題目中整數(shù)的數(shù)值范圍為 [?2^31, 2^31 ? 1]淌哟,2^31-1=2147483647, -2^31=-2147483648迹卢,注意最后一位數(shù),即 7 = INT_MAX % 10, 8 = INT_MIN % 10徒仓。
這里我們默認(rèn)判斷數(shù)值是否超出整數(shù)的最大值范圍就好了(假設(shè)是正整數(shù))腐碱,如果有,判斷正負(fù)掉弛,正數(shù)返回 INT_MAX症见,負(fù)數(shù)返回 INT_MIN。