8字符串轉換整數

題目描述

請你來實現一個 atoi 函數,使其能將字符串轉換成整數。

首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。接下來的轉化規則如下:

如果第一個非空字符爲正或者負號時,則將該符號與之後面儘可能多的連續數字字符組合起來,形成一個有符號整數。
假如第一個非空字符是數字,則直接將其與之後連續的數字字符組合起來,形成一個整數。
該字符串在有效的整數部分之後也可能會存在多餘的字符,那麼這些字符可以被忽略,它們對函數不應該造成影響。
注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不需要進行轉換,即無法進行有效轉換。

在任何情況下,若函數不能進行有效的轉換時,請返回 0 。

提示:

  • 本題中的空白字符只包括空格字符 ’ ’ 。
  • 假設我們的環境只能存儲 32 位大小的有符號整數,那麼其數值範圍爲 [−2^31, 2^31 − 1]。如果數值超過這個範圍,請返回 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31) 。

思路分析

題目很清晰地給出了轉化規則,我們需要將其轉化爲代碼。

  1. trim() 將字符串首部的空格去除;
  2. 判斷第一個字符:
    • 爲 ‘-’ 則將標誌位置爲 -1 ,從第二位開始算;
    • 爲 ‘+’ 則將標誌位置爲 1 ,從第二位開始算;
    • 爲除數字 0-9 外的字符直接返回。
  3. 主要問題在 int 的邊界問題上。
    1. 最小負數
      • int的最大正數的絕對值小於最小負數絕對值。我們需要讓符號位也參與運算過程,避免最後置負時超出邊界。’+’ => 1;’-’=> -1。
    2. 數值越界
      • 在每次循環時,通過INT_MAX/10的值提前判斷是否越界。
      • value > INT_MAX/10 時,說明擴大10倍後,value 必將越界。
      • 當 value == INT_MAX/10 時,說明擴大10倍後,value 可能越界,也可能不越界,需要利用當前的加數 digit 做進一步的判斷:正數是當 digit > 7 時,越界;複數是當 digit > 8 時,越界。
      • 當 value < INT_MAX/10 時,本輪循環必不越界。
    3. 正負數越界判斷合併
      • 將-1、1轉換爲0、1 => (isNegative + 1) / 2 + digit > 8時,數值越界。

綜上所述,
overValue = isNegative * value - INT_MAX/10
+ (((isNegative+1)/2 + digit > 8) ? 1:0);

當overValue>0時,數值將會越界,反之不會。

代碼實現

    public static int myAtoi(String str) {
        if(str==null||str.length()==0){
            return 0;
        }
        str = str.trim();
        if(str==null||str.length()==0){
            return 0;
        }
        int isSub = 1;
        int sum = 0,overvalue = 0,digit = 0,index = 0;

        if (str.charAt(0) == '-') {
            isSub = -1;
            index = 1;
        } else if (str.charAt(0) == '+') {
            isSub = 1;
            index = 1;
        } else if (str.charAt(0) > '9' || str.charAt(0) < '0') {
            return 0;
        }

        for (int i = index; i <= str.length() - 1; i++) {
            digit = str.charAt(i) - '0';
            overvalue = isSub * sum - Integer.MAX_VALUE / 10 + (((isSub + 1) / 2 + digit > 8) ? 1 : 0);
            if ((digit < 0 || digit > 9)) {
                break;
            } else if (overvalue > 0) {
                return isSub == -1 ? Integer.MIN_VALUE : Integer.MAX_VALUE;
            }
            sum = sum * 10 + isSub * digit;
        }

        return sum;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章