当前位置: 首页 > 知识库问答 >
问题:

递归for循环上下文中的NaN

怀经赋
2023-03-14

我试图理解我为一个问题找到的解决方案:“给你不同面额的硬币和总金额。写一个函数来计算组成该金额的组合数。你可以假设每种硬币的数量是无限的。”

我的问题是,如果我用change(3,[2])运行函数,为什么它会输出0。我很难理解在一个递归调用currentCoin变得未定义之后,当程序到达该调用中的for循环时,它是如何不再调用change函数的total=change(amount-0*undefined,coins.slice(0,-1))。为什么它不会在change(NaN,[])coins的无限递归调用中崩溃。片(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]))

共有3个答案

诸腾
2023-03-14
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

卜凯旋
2023-03-14

不是崩溃,因为一个NaN与一个数字相比是完全错误的。。。楠

qty * currentCoin <= amount

evaluate为false,将退出for。

所以,如果你需要检查NaN,你必须在

let totalCoin = qty * currentCoin;
let check = isNaN(totalCoin);
if(check) {
  // return you sentinel value;
}
宇文卓
2023-03-14

这里发生了几件事。

首先是硬币[coins.length-1]的行为。在Javascript中,当您在列表中不存在的索引处访问列表的元素时,索引器将返回undefined,而不是使用IndexOutOfBoundsException或类似方法崩溃。

第二个是qty*currentCoin

把这些放在一起,您会看到,在第一次递归中,coins数组将为空,这使得currentCoinNaN。这导致数量*currentCoin

如果您在有关函数的战略位置插入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]))

 类似资料:
  • 问题内容: 这两种获取阶乘(循环与递归)的方法中哪种更有效/更快?如果可以改进,那又如何呢? 语言:Java 问题答案: 因为没有方法调用的开销,所以for循环将更加有效。(作为一般规则,循环几乎总是比递归更有效率) 为了解释为什么您必须深入了解调用方法和调用堆栈时发生的事情。 基本上,当您调用一个方法时,它需要一些空间来使用(例如其局部变量之类的东西),它还需要空间以用于将传入的参数传递给它,并

  • 问题内容: 是否每个递归函数都有一个等效的for循环?(两者都达到相同的结果)。 我有这个递归函数: 假设单词是Set [],并且单词[i] =单词长度为i的集合。 我想做的是:使用一个单词(例如,“ stackoverflow”,没有空格)启动递归,我试图查找该单词是否可以切成子单词(“ stack”,“ over”,“ flow”) ..子词的最小长度为3,并且假设长度为i的子词在Set wo

  • 我在一个名为“y”的列表中有一个大约28K个数字的列表,我正在API上运行for循环来发送消息,但这需要很多时间(确切地说,每次调用1.2797秒) 代码: 我怎样才能减少做这件事的时间?

  • 我正在编写一个计算e^x值的方法。我在python中实现它的方式如下。 这将很好地返回e^x的值。但是,当我尝试在c#中实现相同的方法时,它没有输出与python中相同的值。以下是c#中的实现。 起初,这段代码的输出是一个无穷大符号。为了解决这个问题,我只是减少了循环运行的次数。在c#中,循环只运行10次,代码的输出非常接近于python中循环运行100次的输出。我的问题是,在不同的编程语言中,两

  • if语句 (实际上是if表达式) OCaml有两种if语句: if boolean-condition then expression if boolean-condition then expression else other-expression 不同于传统的语言,if语句是表达式。它们更类似于C类语言中的三元操作符?: 而不是你所熟悉的if语句。 下面是if语句的简单例子: # le