簡體   English   中英

雖然循環有兩個嵌套的 for 循環輸出無限循環,但我做錯了什么?

[英]While loop with two nested for loops outputting infinite loop, what am I doing wrong?

我正在制作一個程序,該程序將任意隨機的 integer 加起來其各個值並創建一個總和。 如果轉換為字符串形式后的總和長度大於 1,則繼續將 integer 個值相加,直到得到 1 位數的總和。

我的代碼問題是我預期的 output 對於值為 1 位的隨機數已經會立即返回該數字,如果數字大於 1 的數字加起來是另一個大於 1 位的數字,它不會重復循環而是陷入無限循環。

let digitalRoot = (n) => {
  let stringNum = n.toString();
  let refArr = [];
  let result = 0;
  let iterator = refArr.values();

  while (stringNum.length > 1) {
    
    for (let i = 0; i < stringNum.length; i++) {
      let stringVal = stringNum[i];
      stringVal = parseInt(stringVal);
      refArr.push(stringVal)
    }
    
    for (let number of iterator) {
      if (result !== number) {
        result = result + number;
      }
      else {
        result = result + number;
      }
    }
    
    result = result.toString();
    if (result.length === 1) {
      result = parseInt(result);
      return result;
    }

    refArr = [];
    stringNum = result.toString();

  }

  if (stringNum.length === 1) {
    stringNum = parseInt(stringNum);
    return stringNum;
  }

}

例如1455的預期 output 應該是6 ,因為1 + 4 + 5 + 5 = 15 1 + 5 = 6

更新

我知道我在問題中的原始代碼效率低下,但我能夠通過編輯一些東西來獲得預期的結果,首先是將 refArr 和迭代器變量移動到 while 循環中,將結果重置為 0 並進行一些其他修改。 顯然我的代碼是非常非常低效的解決方案,不推薦使用,但我想將我的代碼作為練習等進行更正。

let digitalRoot = (n) => {
  let stringNum = n.toString();
  let result = 0;

  while (stringNum.length > 1) {
    let refArr = [];
    let iterator = refArr.values();

    for (let i = 0; i < stringNum.length; i++) {
      let stringVal = stringNum[i];
      stringVal = parseInt(stringVal);
      refArr.push(stringVal)
    }

    for (let number of iterator) {
      if (result !== number) {
        result = result + number;
      }
      else {
        result = result + number;
      }
    }

    let tester = result.toString();
    if (tester.length === 1) {
      tester = parseInt(tester);
      return tester;
    }

    stringNum = result.toString();
    result = 0;
    refArr = [];
  }

  if (stringNum.length === 1) {
    stringNum = parseInt(stringNum);
    return stringNum;
  }

}

你可以這樣做...

 const digitalRoot = n => { while (n > 10) n = [...n.toString(10)].reduce((s,v)=>s + +v,0) return n } console.log( digitalRoot( 1455 ))

一些點...

.toString()
n.toString(10)12546更改為'12546'

傳播語法 (...)
...'123456''12546'更改為'1','2','3','4','5','6' (迭代)
所以
[...'123456']創建一個數組 = [ '1','2','3','4','5','6' ]

數組.reduce()

+v字符串前的一元加號 (+)是:如文檔中所寫:
一元加號運算符 (+) 在其操作數之前並對其求值,但嘗試將其轉換為數字。

解釋這里使用的reduce方法:
[ '1','2','3','4','5','6' ].reduce((s,v) => s + +v, 0)
做:

step 0  s =  0, v = '1' ->  0 + +'1' =  0 + 1 = 1 
step 1  s =  1, v = '2' ->  1 + +'2' =  1 + 2 = 3 
step 2  s =  3, v = '3' ->  3 + +'3' =  3 + 3 = 6 
step 3  s =  6, v = '4' ->  3 + +'4' =  6 + 4 = 10 
step 4  s = 10, v = '5' -> 10 + +'5' = 10 + 5 = 15 
step 5  return 15

如果 n 為負數會怎樣? 為此,我們假設 n >= 0。 真的不清楚為什么你有 2 個循環,而第二個循環對某事進行了測試,但無論如何都做同樣的事情。

  • 通常,盡量避免使同一個變量有時是數字有時是字符串。 "15" + 1 = "151"15 + 1 = 16
  • 在循環開始時重置累加器。
  • 很少需要在循環之前獲取迭代器

簡化版:

let digitalRoot = (n) => {
  while (n >= 10) {
    // convert to decimal
    let stringNum = n.toString();
    let result = 0
    for (let i = 0; i < stringNum.length; i++) {
      result +=  parseInt(stringNum[i]);
    }
    n = result
  }
  return n
}

更簡單的方法是使用reduce() ,這個更高的 function 迭代一個值數組,並在每次迭代時減少這些值的數量,同時用數組中的下一個值計算累積的前一個值。

將字符串拆分為一個數組,然后 map 將其返回一個數字,並減少每次迭代時將累加器添加到返回值。

 const num = 1455; const num2 = 35714; const num3 = 11211; const sumUp = (num) => { return String(num).split('').map(Number).reduce((a, c) => a + c); } console.log(sumUp(num), sumUp(num2), sumUp(num3))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM