水仙花數

來自 LIOJ,還蠻值得練習的題目。

解題方向

  1. 怎麼知道一個數字有幾位數?
  2. 怎麼取出每個位數的數字?

求出位數

把一個數字一直 /10(記得無條件捨去),直到 0 為止。看總共除幾次,就代表這個數字有幾位數:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function digitCount(n) {
// n=0 時會被當作 0 位數,所以做點處理
if(n === 0) return 1
let result = 0
// 直到 0 為止
while(n !== 0) {
n = Math.floor(n/10)
result++
}
return result
}
digitCount(0) // 1
digitCount(12) // 2
digitCount(123) // 3

取出每個位數的數字

對一個數字取餘數 %10 可以取到「最後一位數字」,接著搭配迴圈使用 /10 來更新數字(去掉最後一位數),就可以取出每一個位數的數字:

1
2
3
4
5
6
7
8
function printSingleDigit(n) {
while(n !== 0) {
const number = n % 10
console.log(number)
n = Math.floor(n/10)
}
}
printSingleDigit(123)

輸出結果:

1
2
3
3
2
1

解法

上面問題搞定後,接下來只要依據水仙花數的定義來解題即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function isNarcissistic(n) {
// 幾位數
let digit = digitCount(n)
// 儲存每一位數的加總
let sum = 0
// 複製一份數字
let m = n
// 計算總和
while(m !== 0) {
// 每一位數 x 位數
sum += (m%10) ** digit
// 去除最後一位數
m = Math.floor(m/10)
}
console.log(sum === n)
}
isNarcissistic(5) // true
isNarcissistic(1634) // true
isNarcissistic(1024) // false

這裡做兩個小提醒:

  1. n 的值必須拷貝一份,不然最後會變成 0,也就沒辦法做 sum === n 的判斷
  2. m%10 ** digit,其中 m%10 必須括號起來,否則會先計算 10**digit

作弊解法-轉成字串

前面是用正統的數學計算來取得每一位數還有總位數,但你仔細想想,如果變成字串的話,要做到那些事就容易很多,例如說 '123'

  1. 取得每一位數 str[0] = 1 str[1] = 2 str[2] = 3
  2. 取得總位數 str.length = 3

所以把剛剛的例子改寫一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function isNarcissisticString(n) {
// 轉成字串
const str = n + ''
// 總位數
const digits = str.length
let sum = 0
for(let i=0; i<str.length; i++) {
sum += Number(str[i]) ** digits
}
console.log(sum === n)
}
isNarcissisticString(5) // true
isNarcissisticString(1634) // true
isNarcissisticString(1024) // false

一樣可以求出正確的結果唷!

JavaScript 中的科學記號表示法 印出聖誕樹
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×