1. 程式人生 > 其它 >字串轉換整數JS

字串轉換整數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;
    }
};