亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

遞歸 for 循環上下文中的 NaN

遞歸 for 循環上下文中的 NaN

肥皂起泡泡 2022-10-27 10:46:04
我試圖理解我為一個問題找到的解決方案:“給你不同面額的硬幣和總金額。編寫一個函數來計算構成該金額的組合數量。你可以假設你有無限每種硬幣的數量?!蔽业膯栴}是,如果我使用 change(3,[2]) 運行該函數,為什么它會吐出 0。我無法理解在單個遞歸調用 currentCoin 之后如何變得未定義,然后當程序到達 for在該調用中循環,它不會再次使用total += change(amount - 0 * undefined, coins.slice(0, -1)). 為什么它不會因無限遞歸調用change(NaN,[])或coins.slice(0,-1)在空數組上使用而崩潰。在 for 循環中似乎忽略了這一點。我是否誤解了 for 循環的工作原理?var change = function(amount, coins) {    if(amount == 0) return 1;         let currentCoin = coins[coins.length - 1];    let total = 0;    for(let qty = 0; qty * currentCoin <= amount; qty++){        total += change(amount - qty * currentCoin, coins.slice(0, -1))    }    return total;};console.log(change(3,[2]))
查看完整描述

4 回答

?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

這里發生了幾件事。


首先是 的行為coins[coins.length - 1]。在 Javascript 中,當您在該列表中不存在的索引處訪問列表的元素時,索引器將返回undefined而不是與 anIndexOutOfBoundsException或類似內容一起崩潰。


二是qty * currentCoin <= amount。在currentCoin未定義的情況下(由于上述原因),qty * currentCoin將為NaN. 在 Javascript 中,任何NaN與另一個數字的比較都會按設計返回 false。(例如NaN <= anything是假的)。


把這一切放在一起,你會看到,在第一次遞歸時,coins數組將為空,這使得currentCoinNaN。這會導致qty * currentCoin <= currentAmount錯誤,從而導致循環短路(因此slice永遠不會在空列表上調用)。由于循環永遠不會執行,total因此仍將為 0,這就是返回的內容。這一直持續到qty * currentCoin <= amount在最外層遞歸中變為真,并且該循環退出時total仍然等于 0(因為它只添加了 0)。


如果您console.log在有關該功能的戰略位置散布調用,那么正在發生的事情會變得更加清晰:


var change = function(amount, coins) {

  console.log(amount, coins);

  if(amount == 0) return 1; 


  let currentCoin = coins[coins.length - 1];

  console.log(':', currentCoin, amount);

  let total = 0;


  for(let qty = 0; qty * currentCoin <= amount; qty++){

    total += change(amount - qty * currentCoin, coins.slice(0, -1))

    console.log('=', total);

  }


  console.log('recdone');

  return total;

};


console.log(change(3,[2]))


查看完整回答
反對 回復 2022-10-27
?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

var change = function(amount, coins) {

    if(amount == 0) return 1; 

    

    let currentCoin = coins[coins.length - 1]; // firstpass 1-1 = 0, second pas 0-1=-1 => coins[-1] = undefined 

    let total = 0;

                   // this will 0*0<=3, second pass 0*undefined => null which is false hence never execute      

    for(let qty = 0; qty * currentCoin <= amount; qty++){

        total += change(amount - qty * currentCoin, coins.slice(0, -1))

    }


    return total;

};


console.log(change(3,[2]))

在第二遍時,coins.length = 0 然后


let currentCoin = coins[0 - 1]; // = undefined 

稍后在 for 循環中,您將 0 * undefined ( qty * currentCoin) 導致 NaN 不是數字


查看完整回答
反對 回復 2022-10-27
?
慕的地6264312

TA貢獻1817條經驗 獲得超6個贊

不會崩潰,因為與數字相比,NaN 都是錯誤的... NaN < number or NaN > number 等等都會產生錯誤...所以


qty * currentCoin <= amount

評估為 false 并將從 for 中退出。


所以,如果你需要檢查 NaN 你必須在 for


let totalCoin = qty * currentCoin;

let check = isNaN(totalCoin);

if(check) {

  // return you sentinel value;

}


查看完整回答
反對 回復 2022-10-27
?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

在這種情況下不需要遞歸??梢允褂米韵露系膭討B規劃方法。讓ways[i]表示i用給定硬幣獲得美元的方式數量,并coins[i]表示i第 th 個硬幣的價值。然后,是從 1 到硬幣數量的所有ways[i]的總和。ways[i - coins[j]]j


var change = function(amount, coins) {

    const ways = Array(amount + 1);

    ways[0] = 1;

    for(const coin of coins){

      for(let i = coin; i <= amount; i++){

        ways[i] = (ways[i] ?? 0) + ways[i - coin] ?? 0;

      }

    }

    return ways[amount];

};

console.log(change(5,[1,2,3,4,5]))


查看完整回答
反對 回復 2022-10-27
  • 4 回答
  • 0 關注
  • 116 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號