字符串轉(zhuǎn)換整數(shù) (atoi)【LeetCode:8】

  1. 題目描述

請(qǐng)你來實(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ì)存在多余的字符,這些字符可以被忽略,它們對(duì)于函數(shù)不應(yīng)該造成影響。
注意:假如該字符串中的第一個(gè)非空格字符不是一個(gè)有效整數(shù)字符、字符串為空或字符串僅包含空白字符時(shí),則你的函數(shù)不需要進(jìn)行轉(zhuǎn)換。
在任何情況下,若函數(shù)不能進(jìn)行有效的轉(zhuǎn)換時(shí),請(qǐng)返回 0。

說明:

假設(shè)我們的環(huán)境只能存儲(chǔ) 32 位大小的有符號(hào)整數(shù),那么其數(shù)值范圍為 [?231, 231 ? 1]。如果數(shù)值超過這個(gè)范圍,qing返回 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) 。

題目解析

這道題目比較長,因?yàn)楫惓G闆r太多了,整體讀完需要獲取的信息如下:

  • 字符串轉(zhuǎn)為數(shù)字,非法輸入時(shí)返回0
  • 數(shù)字前面出現(xiàn)“-”則為負(fù)數(shù),“+”或者直接數(shù)字開頭為正數(shù),其他字符開頭直接判為非法輸入

比如: “ 0=” 輸出為 0, “a001" 輸出為0,“+-”輸出為0,“.1”輸出為0

  • int為32有符號(hào)型,所以輸入輸出有上限和下限

總結(jié)一下就是:將字符串第一個(gè)非空連續(xù)字符轉(zhuǎn)為int(32bit)輸出,未能成功轉(zhuǎn)換輸出0

java第二版本實(shí)現(xiàn),簡化了邏輯,優(yōu)化了字符串轉(zhuǎn)數(shù)字邏輯,執(zhí)行實(shí)現(xiàn)從4ms變?yōu)楝F(xiàn)在的2ms。

java第二版本實(shí)現(xiàn)
static final int max = Integer.MAX_VALUE/10;
int myAtoi(String str) {
    // 非法情況直接返回,節(jié)省時(shí)間
    if (str == null || str.isEmpty()) return 0;
    // trim一下,簡化邏輯
    String trimmed = str.trim();
    if (trimmed.isEmpty()) return 0;
    // 非空第一個(gè)字符,決定正負(fù),確認(rèn) 起始遍歷的index
    boolean isPositive = true;
    int s = 0, length = trimmed.length();
    char c = trimmed.charAt(0);
    if (c == '-') {
        isPositive = false;
        s = 1;
    } else if (c == '+') {
        s = 1;
    }
    // str to int
    int result = 0, current;
    for (int i = s; i < length; i++) {
        current = trimmed.charAt(i) - 48;
        if (current > 9 || current < 0)  break;
        if (result > max || (result == max && current > 7)) {
            return isPositive ? Integer.MAX_VALUE : Integer.MIN_VALUE;
        }
        result = result * 10 + current;
    }
    return isPositive ? result : -result;
}

以下為舊版本實(shí)現(xiàn),看起來比較啰嗦,也沒有真正的在運(yùn)行時(shí)支持32為存儲(chǔ),中間用了long型做轉(zhuǎn)換。

/**
* @author yangbixuan
* @param str 輸入,肯定非空
* @return 解析結(jié)果
*/
public int myAtoi(String str) {
    System.out.print("\"" + str + "\" >>>> ");
    // 非法情況直接返回,節(jié)省時(shí)間
    if (str == null || str.isEmpty()) {
        return 0;
    }
    // trim一下,簡化邏輯
    String trimed = str.charAt(0) == ' ' ? str.trim() : str;
    if (trimed.isEmpty()) {
        return 0;
    }
    // 非空第一個(gè)字符,決定正負(fù),確認(rèn) 起始遍歷的index
    Boolean isPositive = null;
    int s , length = trimed.length();
    char c = trimed.charAt(0);
    if (c == '-') {
        isPositive = false;
        s = 1;
    } else if (c == '+') {
        isPositive = true;
        s = 1;
    } else if (c >= '0' && c <= '9') {
        isPositive = true;
        s = 0;
    } else {
        return 0;
    }
    // 開始搜尋連續(xù)有效的數(shù)字,跳過前綴的0
    int e = s;
    boolean start = false;
    for (int i = s; i < length; i++) {
        char ch = trimed.charAt(i);
        if (ch >= '0' && ch <= '9' && e - s <= 10) {
            if (!start && ch == '0') {
                s = i;
                e = s + 1;
                continue;
            }
            start = true;
            e++;
        } else {
            break;
        }
    }
    // 解析結(jié)果,簡單情況直接計(jì)算,過長的用long接收并截?cái)?    if (s == e || e == 0) {
        return 0;
    } else if (e - s == 1) {
        int result = trimed.charAt(s) - '0';
        return isPositive ? result : 0 - result;
    }
    String num = trimed.substring(s, e);
    if (num.length() < 10) {
        int result = Integer.parseInt(num);
        return isPositive ? result : 0 - result;
    } else {
        long result = Long.parseLong(num);
        if (isPositive) {
            return result >= 2147483647L ? Integer.MAX_VALUE : (int)result;
        } else {
            return result >= 2147483648L ? Integer.MIN_VALUE :  (int)(0 - result);
        }
    }
}

題解:楊比軒
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/string-to-integer-atoi

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容