翻轉一個整數

YancyCathy發表於2020-10-01

今天又是給大家分享一個小的知識點 – 翻轉一個整數

相信我,知識點so so so easy……,並且很容易理解。

好了,閒話我們們就不多說了,直接開始今天的正題吧。

首先先來看下題目是什麼。

實現一個整數的翻轉

如:

  1. 初始值:123,翻轉後:321
  2. 初始值:-123,翻轉後:-321

首先不看答案,按照自己的想法來解答一遍。


1. 第一版

有多少同學看到題目的瞬間想起來的是下面這種解法、

  • 首先將數字轉換為字串
  • 然後判斷第一個字元
    • 如果是符號,則擷取第一個字元後的內容
    • 如果不是符號,則擷取全部
  • 然後將得到的字串進行 str.split('') 操作
  • 之後將得到的陣列進行 reverse
  • 然後判斷是否要新增符號字首
  • 最後得到正確答案。

?栗子:

function reverseInt (n) {
  let str = `${n}`.split('')
  let firstChar = str[0]

  if (firstChar === '-') {
    str = str.slice(1)
  } else {
    firstChar = ''
  }
  str = str.reverse().join('')
  return (firstChar + str) * 1
}

接下來我們就來分析一下這個解法的優勢和劣勢

優勢:
  • 容易理解,我們可以很清楚的知道每一步的執行原理 (貌似只有這一個優點)
劣勢:
  • 資源浪費
    • 需要先將數字轉換為字串
    • 然後切分為陣列
    • 然後翻轉陣列
    • 之後再轉為字串
    • 最後轉換為數字。
  • 並且還需要關注當前整數是負數還是正數。

當然,這個解法肯定是對的,這個是毋庸置疑的,而且每個人都有每個人的理解。

但是~~

這裡還是要有但是,寫程式碼嘛,總得有點兒追求,追求用更省事省力的方式來解決問題。

下面我們再來看另一種解法

2. 第二版

接下來說的這種版本屬於數學運算的版本,但是也是比較好理解的一種。

好,不多說,我們直接來看下小栗子吧!

?栗子:

function reverseInt (n) {
  let result = 0

  while(n) {
    let b = n % 10
    n = ~~(n / 10)
    result = result * 10 + b
  }
  return result
}

初看可能會有點兒不理解,莫慌,我們來解釋一下如何實現的。

解釋:
  • 首先,我們定義了一個結果變數 result 用來儲存我們的執行結果。
  • 迴圈變數 n ,知道 n0 才結束。
  • 接下來是重頭戲,也是這個演算法的核心實現。
    • 每次迴圈都會將n的個位數值儲存下來。
    • 然後讓n的長度減 1
    • 然後讓結果變數每次十倍之後新增我們儲存的數值。
  • 迴圈結束後將 result 變數返回。
  • 這裡我們用到了這樣一個運算子 ~~ ,這個是位運算。在這裡表示對運算結果取整。(詳細知識點可以檢視我之前的文章喲)
流程詳解:

接下來,我們通過原始值 123 來檢視下這個演算法的執行步驟吧。

第一次迴圈:

n = 123

result = 0

b = 123 % 10 = 3

n = 123 / 10 取整 = 12

result = 0 * 10 + 3 = 3

第二次迴圈:

n = 12

result = 3

b = 12 % 10 = 2

n = 12 / 10 取整 = 1

result = 3 * 10 + 2 = 32

第三次迴圈:

n = 1

result = 32

b = 1 % 10 = 1

n = 1 / 10 取整 = 0

result = 32 * 10 + 1 = 321

到這裡整個的演算法已經執行結束。通過驗證我們可以發現一個問題,此演算法對於負數來說同樣有效。

接下來我們來看下這個演算法的優勢

優勢:
  • 不必關注是否是負數。
  • 節省了大量轉換的成本。
  • 節省了空間
  • 利用了數學計算,避免了操作字串和陣列帶來的時間消耗。

OK,到這裡我們今天的分享內容就結束咯。

同樣,期待能給你帶來不一樣的理解和感悟。

Bye~

相關文章