3種方法:字符串轉(zhuǎn)換整數(shù) (atoi)

題目

NO. 8

請(qǐng)你來實(shí)現(xiàn)一個(gè) atoi 函數(shù)萄传,使其能將字符串轉(zhuǎn)換成整數(shù)畦浓。

首先源葫,該函數(shù)會(huì)根據(jù)需要丟棄無用的開頭空格字符产还,直到尋找到第一個(gè)非空格的字符為止。接下來的轉(zhuǎn)化規(guī)則如下:

  1. 如果第一個(gè)非空字符為正或者負(fù)號(hào)時(shí)屯蹦,則將該符號(hào)與之后面盡可能多的連續(xù)數(shù)字字符組合起來维哈,形成一個(gè)有符號(hào)整數(shù)盯漂。
  2. 假如第一個(gè)非空字符是數(shù)字,則直接將其與之后連續(xù)的數(shù)字字符組合起來笨农,形成一個(gè)整數(shù)就缆。
  3. 該字符串在有效的整數(shù)部分之后也可能會(huì)存在多余的字符,那么這些字符可以被忽略谒亦,它們對(duì)函數(shù)不應(yīng)該造成影響竭宰。

注意:假如該字符串中的第一個(gè)非空格字符不是一個(gè)有效整數(shù)字符、字符串為空或字符串僅包含空白字符時(shí)份招,則你的函數(shù)不需要進(jìn)行轉(zhuǎn)換切揭,即無法進(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è)范圍十气,請(qǐng)返回 INT_MAX (231 ? 1) 或 INT_MIN (?231) 励背。

示例 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) 。


解法一(反向排除法Python)

思路:首先對(duì)字符串進(jìn)行處理蝶涩,先排除各種意外情況理朋,則剩下的部分即為有效數(shù)字絮识。

  1. 處理字符開頭的空格绿聘、’0‘、正負(fù)號(hào)
  2. 讀取有效數(shù)值組成的字符集合
  3. 使用字符串比較來判斷是否越界次舌,返回有效字符
  • 時(shí)間復(fù)雜度:O(n)
  • 空間復(fù)雜度:O(n)
#author: suoxd123@126.com
class Solution:
    def myAtoi(self, str1: str) -> int:
        str1 = str1.lstrip()
        if len(str1) == 0:
            return 0
        idx,flag = 0, True
        if str1[0] == '-': #提取符號(hào)
            flag = False
            str1 = str1[1:]
        elif str1[0] == '+':
            str1 = str1[1:]
        while len(str1) > 0 and str1[0] == '0': #去掉0開頭
            str1 = str1[1:]
        while idx < len(str1):#提取有效數(shù)字
            if not('0' <= str1[idx] <= '9'):
                break
            idx += 1
        numStr = str1[0:idx]
        numMaxStr, numMinStr = str(2**31 - 1), str(2**31)
        if idx == 0: #長(zhǎng)度為0
            return 0
        elif (idx > 10 or idx == 10 and numStr > numMaxStr) and flag: #大于最大值
            return int(numMaxStr)
        elif (idx > 10 or idx == 10 and numStr > numMinStr) and not flag: #小于最小值
            return -int(numMinStr)
        else:#一般情況
            return int(numStr) * (1 if flag else -1)

解法二(正向檢查C#)

思路:直接對(duì)每個(gè)字符進(jìn)行判斷和審查熄攘,將讀取到的數(shù)值使用Long型變量存儲(chǔ)和查看是否對(duì)Int溢出。

  1. 使用flag標(biāo)記是否進(jìn)入數(shù)值模式彼念,一旦進(jìn)入數(shù)值模式挪圾,任何其它字符出現(xiàn)都將退出
  2. 使用num保存當(dāng)前已經(jīng)記錄的數(shù)值
  3. 任何出現(xiàn)的其它字符都屬于結(jié)束后續(xù)檢查
  • 時(shí)間復(fù)雜度:O(n)
  • 空間復(fù)雜度:O(1)
//author: suoxd123@126.com
public class Solution {
    public int MyAtoi(string str) {
        bool nagetive = false , flag = false;
        long num = 0;
        long minN = 0-(long)Math.Pow(2,31),maxN = (long)Math.Pow(2,31) - 1;
        for(int i=0;i<str.Length;i++)
        {
            if(str[i] == '-' || str[i] == '+')
            {//符號(hào)
                if(flag == true)
                    break;
                flag = true;
                if(str[i] == '-')
                {
                    nagetive = true;
                }
            }
            else if(str[i] <= '9' && str[i] >= '0')
            {//數(shù)值
                flag = true; //標(biāo)記是否已經(jīng)進(jìn)入計(jì)數(shù)模式
                num = num * 10 + (str[i] - '0') * (nagetive?-1:1);                
                if(num>maxN || num < minN)
                {
                    if(num < minN)
                        num = minN;
                    else
                        num = maxN;
                    break;
                }
            }
            else if(str[i] == ' ')
            {//空格
                if(flag == true)
                    break;
                continue;
            }
            else
            {//其它字符
                break;
            }
        }
        return (int)(num);          
    }
}

解法三(有限狀態(tài)機(jī) C語言)

思路:使用狀態(tài)機(jī)的思路來浅萧,搞清楚不同狀態(tài)之間的切換關(guān)系即可,本題根據(jù)空格哲思、符號(hào)洼畅、數(shù)值和其它字符4種類型,可以定義開始棚赔、符號(hào)帝簇、數(shù)值和結(jié)束4個(gè)狀態(tài),狀態(tài)跳轉(zhuǎn)如下表(橫坐標(biāo)為當(dāng)前狀態(tài)靠益,縱坐標(biāo)為當(dāng)前字符丧肴,跳轉(zhuǎn)表指當(dāng)前狀態(tài)遇到當(dāng)前字符的下一個(gè)狀態(tài)):

當(dāng)前狀態(tài) 空格 正負(fù)號(hào) 數(shù)值 其它字符
開始 開始 符號(hào) 數(shù)值 結(jié)束
符號(hào) 結(jié)束 結(jié)束 數(shù)值 結(jié)束
數(shù)值 結(jié)束 結(jié)束 數(shù)值 結(jié)束
結(jié)束 結(jié)束 結(jié)束 結(jié)束 結(jié)束

  1. 定義狀態(tài)跳轉(zhuǎn)矩陣和跳轉(zhuǎn)函數(shù)
  2. 循環(huán)讀取當(dāng)前字符,直到狀態(tài)進(jìn)入結(jié)束
  3. 當(dāng)前結(jié)果轉(zhuǎn)換為字符串
  • 時(shí)間復(fù)雜度:O(n)
  • 空間復(fù)雜度:O(1)
//author: suoxd123@126.com
int getStatus(int lastStatus,char currentChar){//狀態(tài)跳轉(zhuǎn)
    int currentStatus = 0;
    const int status[4][4] = {//狀態(tài)跳轉(zhuǎn)矩陣
        {1,2,3,4},
        {4,4,3,4},
        {4,4,3,4},
        {4,4,4,4}
    };
    if(currentChar == ' '){
        currentStatus = 1;
    }
    else if(currentChar == '+' || currentChar == '-'){
        currentStatus = 2;
    }
    else if(currentChar >= '0' && currentChar <= '9'){
        currentStatus = 3;
    }
    else{
        currentStatus = 4;
    }
    return status[lastStatus-1][currentStatus-1];
}

int myAtoi(char * str){
    int status = 1, sign = 1; //狀態(tài)默認(rèn)是1(開始狀態(tài))
    char numChar = *str++;
    long val = 0;
    int intMax = 0x7FFFFFFF, intMin = -0x80000000;
    while(status < 4 && numChar != '\0'){
        status = getStatus(status,numChar);
        if(status == 2){//符號(hào)
            sign = (numChar == '-' ? -1:1);
        }
        else if(status == 3){//數(shù)值
            val = val * 10 + sign * (numChar - '0');
            if(sign == 1){//檢查向上越界
                val = val > intMax?intMax:val;
            }
            else{//檢查向下越界
                val = val < intMin?intMin:val;
            }
        }
        numChar = *str++;
    }
    return (int)val;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胧后,一起剝皮案震驚了整個(gè)濱河市芋浮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壳快,老刑警劉巖纸巷,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異眶痰,居然都是意外死亡何暇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門凛驮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裆站,“玉大人,你說我怎么就攤上這事黔夭『昕瑁” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵本姥,是天一觀的道長(zhǎng)肩袍。 經(jīng)常有香客問我,道長(zhǎng)婚惫,這世上最難降的妖魔是什么氛赐? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮先舷,結(jié)果婚禮上艰管,老公的妹妹穿的比我還像新娘。我一直安慰自己蒋川,他們只是感情好牲芋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般缸浦。 火紅的嫁衣襯著肌膚如雪夕冲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天裂逐,我揣著相機(jī)與錄音歹鱼,去河邊找鬼。 笑死卜高,一個(gè)胖子當(dāng)著我的面吹牛醉冤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播篙悯,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚁阳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鸽照?” 一聲冷哼從身側(cè)響起螺捐,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矮燎,沒想到半個(gè)月后定血,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诞外,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年澜沟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峡谊。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茫虽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出既们,到底是詐尸還是另有隱情濒析,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布啥纸,位于F島的核電站号杏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏斯棒。R本人自食惡果不足惜盾致,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荣暮。 院中可真熱鬧庭惜,春花似錦、人聲如沸渠驼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迷扇。三九已至百揭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜓席,已是汗流浹背器一。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厨内,地道東北人祈秕。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像雏胃,于是被迫代替她去往敵國(guó)和親请毛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容