字符串轉(zhuǎn)換整數(shù) (atoi)

請(qǐng)你來實(shí)現(xiàn)一個(gè) myAtoi(string s) 函數(shù),使其能將字符串轉(zhuǎn)換成一個(gè) 32 位有符號(hào)整數(shù)(類似 C/C++ 中的 atoi 函數(shù))。

函數(shù) myAtoi(string s) 的算法如下:

  • 讀入字符串并丟棄無用的前導(dǎo)空格
  • 檢查下一個(gè)字符(假設(shè)還未到字符末尾)為正還是負(fù)號(hào)哲泊,讀取該字符(如果有)痰憎。 確定最終結(jié)果是負(fù)數(shù)還是正數(shù)略水。 如果兩者都不存在,則假定結(jié)果為正刹帕。
  • 讀入下一個(gè)字符吵血,直到到達(dá)下一個(gè)非數(shù)字字符或到達(dá)輸入的結(jié)尾。字符串的其余部分將被忽略偷溺。
  • 將前面步驟讀入的這些數(shù)字轉(zhuǎn)換為整數(shù)(即蹋辅,"123" -> 123, "0032" -> 32)挫掏。如果沒有讀入數(shù)字侦另,則整數(shù)為 0 。必要時(shí)更改符號(hào)(從步驟 2 開始)尉共。
  • 如果整數(shù)數(shù)超過 32 位有符號(hào)整數(shù)范圍 [?231, 231 ? 1] 褒傅,需要截?cái)噙@個(gè)整數(shù),使其保持在這個(gè)范圍內(nèi)袄友。具體來說殿托,小于 ?231 的整數(shù)應(yīng)該被固定為 ?231 ,大于 231 ? 1 的整數(shù)應(yīng)該被固定為 231 ? 1 剧蚣。
    返回整數(shù)作為最終結(jié)果支竹。
    注意:

本題中的空白字符只包括空格字符 ' ' 。
除前導(dǎo)空格或數(shù)字后的其余字符串外鸠按,請(qǐng)勿忽略 任何其他字符

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/string-to-integer-atoi
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有礼搁。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處待诅。

問題分析

需要思考如下幾個(gè)問題叹坦。

輸入有幾種類型?哪一部分是我們需要處理的部分
- 數(shù)字
- 整數(shù)范圍內(nèi)
- 正整數(shù)
- 負(fù)整數(shù)
- 0
- 整數(shù)范圍外
- 小于最小邊界值
- 大于最大邊界值
- 非數(shù)字
- 混合數(shù)組
- 前數(shù)字后子母
- 前字母后數(shù)字
- 中間數(shù)字
- 純字母

根據(jù)題目進(jìn)行分析:

我們需要處理的內(nèi)容有

  • 正負(fù)數(shù)和0
檢查下一個(gè)字符(假設(shè)還未到字符末尾)為正還是負(fù)號(hào)卑雁,讀取該字符(如果有)募书。 確定最終結(jié)果是負(fù)數(shù)還是正數(shù)。 如果兩者都不存在测蹲,則假定結(jié)果為正莹捡。
  • 混合數(shù)字的前數(shù)字后字母
讀入下一個(gè)字符,直到到達(dá)下一個(gè)非數(shù)字字符或到達(dá)輸入的結(jié)尾扣甲。字符串的其余部分將被忽略篮赢。
  • 其他非數(shù)字類型輸出0
 將前面步驟讀入的這些數(shù)字轉(zhuǎn)換為整數(shù)(即,"123" -> 123琉挖, "0032" -> 32)启泣。如果沒有讀入數(shù)字,則整數(shù)為 0 示辈。必要時(shí)更改符號(hào)(從步驟 2 開始)
  • 整數(shù)范圍之外輸出邊界值
如果整數(shù)數(shù)超過 32 位有符號(hào)整數(shù)范圍 [?231,  231 ? 1] 寥茫,需要截?cái)噙@個(gè)整數(shù),使其保持在這個(gè)范圍內(nèi)矾麻。具體來說纱耻,小于 ?231 的整數(shù)應(yīng)該被固定為 ?231 芭梯,大于 231 ? 1 的整數(shù)應(yīng)該被固定為 231 ? 1 。

綜上我們將其流程總結(jié)為:


轉(zhuǎn)換主流程

那么我們針對(duì)每個(gè)流程進(jìn)行梳理

  1. 前導(dǎo)空格去除
    從前往后遇到第一個(gè)非空格認(rèn)為前導(dǎo)空格去除結(jié)束
  2. 正負(fù)號(hào)判定
    去除空格判定結(jié)束后的下一個(gè)字符是非(-)號(hào)數(shù)字或者字母或者是一個(gè)(-)號(hào)
  3. 數(shù)字字符串提取
    從正負(fù)號(hào)判定之后的第一個(gè)字符開始,遇到下一個(gè)非數(shù)字結(jié)束
  4. 數(shù)字字符串轉(zhuǎn)化
  5. 在整數(shù)范圍 [?231, 231 ? 1] 內(nèi)輸出當(dāng)前數(shù)字
  6. 在下邊界之外,輸出下邊界值
  7. 在上邊界之外弄喘,輸出上邊界值
  8. 結(jié)果輸出
    正常輸出結(jié)果
    第四步衍生子問題:
    邊界值如何判定是否超綱玖喘?
    判定依據(jù):
    1. 長度大于32位
    2. 從左到右依次判定當(dāng)前值是否小于邊界值轉(zhuǎn)換的字符串

則針對(duì)每一個(gè)小點(diǎn)我們可以寫出代碼

  1. 前導(dǎo)空格去除
private String replaceBlank(String s){
            int i = 0;
            for (char c : s.toCharArray()) {
                if (c != ' '){
                    break;
                }else {
                    i++;
                }
            }
            return s.substring(i);
        }
  1. 正負(fù)號(hào)判定
private boolean hasMinus(String c) {
            if (c.charAt(0) == '-'){
                return true;
            }
            return false;
        }
  1. 數(shù)字字符串提取
private String extractionOfDigital(String rplString) {
            StringBuilder builder = new StringBuilder();
            rplString = replaceFirstZero(rplString);
            // 去除前面的0
            for (char c : rplString.toCharArray()) {
                if (c >= '0' && c <= '9'){
                    builder.append(c);
                }else {
                    break;
                }
            }
            return builder.toString();
        }
private String replaceFirstZero(String s){
            int i = 0;
            for (char c : s.toCharArray()) {
                if (c == '0'){
                    i++;
                }else {
                    break;
                }
            }
            return s.substring(i);
        }
  1. 數(shù)字字符串轉(zhuǎn)化
private Integer convertsAStringToANumber(String numStr, boolean hasMinus) {
            if (numStr.equals("")){
                return 0;
            }
            if (numStr.length() > 10){
                if (!hasMinus){
                    return Integer.MAX_VALUE;
                }else {
                    return Integer.MIN_VALUE;
                }
            }
            if (numStr.length() < 10){
                if (hasMinus){
                    return Integer.valueOf("-"+numStr);
                }else {
                    return Integer.valueOf(numStr);
                }
            }
            if (hasMinus){
                // 負(fù)數(shù)
                String minValue = Integer.MIN_VALUE + "";
                int i = 0;
                char[] numStrC = ("-"+numStr).toCharArray();
                boolean isGreaterThanThe = false;
                for (char c : minValue.toCharArray()) {
                    char n = numStrC[i++];
                    if (n > c){
                        isGreaterThanThe = true;
                        break;
                    }else if (n < c){
                        break;
                    }
                }
                if (isGreaterThanThe){
                    return Integer.MIN_VALUE;
                }else {
                    return Integer.valueOf("-"+numStr);
                }
            }else {
                // 正數(shù)
                String minValue = Integer.MAX_VALUE + "";
                int i = 0;
                char[] numStrC = numStr.toCharArray();
                boolean isGreaterThanThe = false;
                for (char c : minValue.toCharArray()) {
                    char n = numStrC[i++];
                    if (n > c){
                        isGreaterThanThe = true;
                        break;
                    }else if (n < c){
                        break;
                    }
                }
                if (isGreaterThanThe){
                    return Integer.MAX_VALUE;
                }else {
                    return Integer.valueOf(numStr);
                }
            }
        }

整體代碼為:

public class Main {
    public static void main(String[] args) {
        new Main().test();
    }
    public void test(){
        System.out.println(new Solution().myAtoi("1095502006p8"));
    }

    class Solution {
        public int myAtoi(String s) {
            if (s == null || s.equals("")){
                return 0;
            }

            // 前導(dǎo)空格去除
            String rplString = replaceBlank(s);
            if (rplString.length() == 0){
                return 0;
            }
            boolean hasMinus = hasMinus(rplString);
            if (rplString.startsWith("-") ||rplString.startsWith("+")){
                rplString = rplString.substring(1);
            }
            String numStr = extractionOfDigital(rplString);


            Integer num = convertsAStringToANumber(numStr,hasMinus);
            return num;
        }

        private Integer convertsAStringToANumber(String numStr, boolean hasMinus) {
            if (numStr.equals("")){
                return 0;
            }
            if (numStr.length() > 10){
                if (!hasMinus){
                    return Integer.MAX_VALUE;
                }else {
                    return Integer.MIN_VALUE;
                }
            }
            if (numStr.length() < 10){
                if (hasMinus){
                    return Integer.valueOf("-"+numStr);
                }else {
                    return Integer.valueOf(numStr);
                }
            }
            if (hasMinus){
                // 負(fù)數(shù)
                String minValue = Integer.MIN_VALUE + "";
                int i = 0;
                char[] numStrC = ("-"+numStr).toCharArray();
                boolean isGreaterThanThe = false;
                for (char c : minValue.toCharArray()) {
                    char n = numStrC[i++];
                    if (n > c){
                        isGreaterThanThe = true;
                        break;
                    }else if (n < c){
                        break;
                    }
                }
                if (isGreaterThanThe){
                    return Integer.MIN_VALUE;
                }else {
                    return Integer.valueOf("-"+numStr);
                }
            }else {
                // 正數(shù)
                String minValue = Integer.MAX_VALUE + "";
                int i = 0;
                char[] numStrC = numStr.toCharArray();
                boolean isGreaterThanThe = false;
                for (char c : minValue.toCharArray()) {
                    char n = numStrC[i++];
                    if (n > c){
                        isGreaterThanThe = true;
                        break;
                    }else if (n < c){
                        break;
                    }
                }
                if (isGreaterThanThe){
                    return Integer.MAX_VALUE;
                }else {
                    return Integer.valueOf(numStr);
                }
            }
        }

        private String extractionOfDigital(String rplString) {
            StringBuilder builder = new StringBuilder();
            rplString = replaceFirstZero(rplString);
            // 去除前面的0
            for (char c : rplString.toCharArray()) {
                if (c >= '0' && c <= '9'){
                    builder.append(c);
                }else {
                    break;
                }
            }
            return builder.toString();
        }
        private String replaceFirstZero(String s){
            int i = 0;
            for (char c : s.toCharArray()) {
                if (c == '0'){
                    i++;
                }else {
                    break;
                }
            }
            return s.substring(i);
        }
        private boolean hasMinus(String c) {
            if (c.charAt(0) == '-'){
                return true;
            }
            return false;
        }

        private String replaceBlank(String s){
            int i = 0;
            for (char c : s.toCharArray()) {
                if (c != ' '){
                    break;
                }else {
                    i++;
                }
            }
            return s.substring(i);
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蘑志,隨后出現(xiàn)的幾起案子累奈,更是在濱河造成了極大的恐慌,老刑警劉巖卖漫,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件费尽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡羊始,警方通過查閱死者的電腦和手機(jī)旱幼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來突委,“玉大人柏卤,你說我怎么就攤上這事≡扔停” “怎么了缘缚?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長敌蚜。 經(jīng)常有香客問我桥滨,道長,這世上最難降的妖魔是什么弛车? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任齐媒,我火速辦了婚禮,結(jié)果婚禮上纷跛,老公的妹妹穿的比我還像新娘喻括。我一直安慰自己,他們只是感情好贫奠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布唬血。 她就那樣靜靜地躺著,像睡著了一般唤崭。 火紅的嫁衣襯著肌膚如雪拷恨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天谢肾,我揣著相機(jī)與錄音挑随,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛兜挨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眯分,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拌汇,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了弊决?” 一聲冷哼從身側(cè)響起噪舀,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎飘诗,沒想到半個(gè)月后与倡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昆稿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年纺座,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溉潭。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡净响,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出喳瓣,到底是詐尸還是另有隱情馋贤,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布畏陕,位于F島的核電站配乓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惠毁。R本人自食惡果不足惜犹芹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仁讨。 院中可真熱鬧羽莺,春花似錦、人聲如沸洞豁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丈挟。三九已至刁卜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曙咽,已是汗流浹背蛔趴。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留例朱,地道東北人孝情。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓鱼蝉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親箫荡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魁亦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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