字符串轉換整數JS


/**
 * @param {string} str
 * @return {number}
 */
var myAtoi = function(str) {
  // 自動機類
  class Automaton{
    constructor() {
      // 執行階段,默認處於開始執行階段
      this.state = 'start';
      // 正負符號,默認是正數
      this.sign = 1;
      // 數值,默認是0
      this.answer = 0;
      /*
      關鍵點:
      狀態和執行階段的對應表
      含義如下:
      [執行階段, [空格, 正負, 數值, 其他]]
      */
      this.map = new Map([
        ['start', ['start', 'signed', 'in_number', 'end']],
        ['signed', ['end', 'end', 'in_number', 'end']],
        ['in_number', ['end', 'end', 'in_number', 'end']],
        ['end', ['end', 'end', 'end', 'end']]
      ])
    }

    // 獲取狀態的索引
    getIndex(char) {
      if (char === ' ') {
        // 空格判斷
        return 0;
      } else if (char === '-' || char === '+') {
        // 正負判斷
        return 1;
      } else if (typeof Number(char) === 'number' && !isNaN(char)) {
        // 數值判斷
        return 2;
      } else {
        // 其他情況
        return 3;
      }
    }

    /*
    關鍵點:
    字符轉換執行函數
    */
    get(char) {
      /*
      易錯點:
      每次傳入字符時,都要變更自動機的執行階段
      */
      this.state = this.map.get(this.state)[this.getIndex(char)];

      if(this.state === 'in_number') {
        /*
        小技巧:
        在JS中,對字符串類型進行減法操作,可以將得到一個數值型(Number)的值

        易錯點:
        本處需要利用括號來提高四則運算的優先級
        */
        this.answer = this.answer * 10 + (char - 0);

        /*
        易錯點:
        在進行負數比較時,需要將INT_MIN變為正數
        */
        this.answer = this.sign === 1 ? Math.min(this.answer, Math.pow(2, 31) - 1) : Math.min(this.answer, -Math.pow(-2, 31));
      } else if (this.state === 'signed') {
        /*
        優化點:
        對於一個整數來說,非正即負,
        所以正負號的判斷,只需要一次。
        故,可以降低其判斷的優先級
        */
        this.sign = char === '+' ? 1 : -1;
      }
    }
  }

  // 生成自動機實例
  let automaton = new Automaton();

  // 遍歷每個字符
  for(let char of str) {
    // 依次進行轉換
    automaton.get(char);
  }

  // 返回值,整數 = 正負 * 數值
  return automaton.sign * automaton.answer;
};
View Code

自動機

我們的程序在每個時刻有一個狀態s,每次從序列中輸入一個字符c,並根據字符c 轉移到下一個狀態s'。

這樣,我們只需要建立一個覆蓋所有情況的從s與c映射到s'的表格即可解決題目中的問題。

來源:力扣(LeetCode)

字符串str中的每個字符,都有可能是以下的四種類型中的一種:

  1. 空格字符' '(Space)
  2. 正負號+和-(Sign)
  3. 字符串型的數值(Number)
  4. 除以上三種情況外的任何情況(Other)

階段分析
如果想要將字符串轉換為整數,那么必然會經歷這四個有序的階段:

  1. 開始轉換(start)
  2. 判斷正負(signed)
  3. 生成數值(in_number)
  4. 結束轉換(end)

梳理為表格形式

 

 

 

 解決的問題:字符串轉換整數 (atoi)

可以想到Javascript 的 parseInt(),使用這個API,進行嘗試。

parseInt(string, radix):

string:要被解析的值。如果參數不是一個字符串,則將其轉換為字符串。字符串開頭的空白符將會被忽略。
radix(可選):需要轉換的進制,介於 2 到 36。
返回值: 如果被解析參數的第一個字符無法被轉化成數值類型,則返回NaN。

  • 無視開頭空格(√)
  • 返回有符號整數(√)
  • 無視整數部分后的字符(√)
  • 范圍在32位內(含)(x)
  • 其他情況返回0(x)

需要注意:

在使用parseInt(string, radix)這一API時,如果不傳入radix參數,會有兩種特殊情況:

如果字符串 string 以"0x"或者"0X"開頭, 則基數是16 (16進制).
如果字符串 string 以"0"開頭, 基數是8(八進制)或者10(十進制),那么具體是哪個基數,取決與ECMAScript的版本。

 

/**
 * @param {string} s
 * @return {number}
 */
var myAtoi = function(s) {
    const number = parseInt(s, 10);

    if(isNaN(number)) {
        return 0;
    } else if (number < Math.pow(-2, 31) || number > Math.pow(2, 31) - 1) {
        return number < Math.pow(-2, 31) ? Math.pow(-2, 31) : Math.pow(2, 31) - 1;
    } else {
        return number;
    }
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM