递归因子函数如何知道何时停止

时间:2017-02-16 22:49:33

标签: javascript algorithm recursion

我正在尝试编写一个递归因子函数来练习我的递归,并想出了这个:

function test(num){
  return (num * test(num - 1))
}

但是,无论何时运行它,它都会永远循环,我得到一个范围错误:超出最大调用堆栈大小。

但如果我写它来处理异常,

function factorial(num) {
    if (num < 0) {
        return -1;
    } else if (num === 0) {
        return 1;
    } else {
        return (num * factorial(num - 1));
    }
}

完美无缺。

2个问题。

  1. 为什么第一个不起作用?

  2. 第二个如何知道何时停止运行。如果num实际上每次将它的值改为-1,它最终会达到0并且它应该触发else if并返回1,但是如果你运行factorial(3)它会返回6.

1 个答案:

答案 0 :(得分:2)

  1. 递归必须具有基本情况 - 函数停止时遇到的条件。

  2. 您将从num转到num-1,依此类推,直至0,此时该函数符合基本情况:num == 0并返回1从这一点开始,递归展开,并乘以1 * num-(num-1) ... num

  3. 此外,factorial仅针对非负整数定义,因此返回-1时没有太大意义。另一件事:基本情况应该是num == 1

    当您1时,您正在做的是乘以num ==1,然后再乘以1 num == 0返回factorial(0).

    的错误因子

    编辑:factorial(0)为1.因此,您确实返回1是正确的,但我仍然会将其视为一个极端情况。无需等待额外的步骤才能达到0。

    function factorial(n){
        // Handle the corner cases: you might as well just throw an error
        if (n < 0) return undefined;
        if (n == 0) return 1;
    
        // Base case
        if (n == 1) return 1;
    
        // Iterative step
        // (If the function got to this point, it means, that n > 1)
        return n * factorial(n - 1);
    
        // In order to return the expression on the right side of "return",
        // You need to calculate the `factorial(n - 1)`
        // When you try calculating it, you will see, that now you need to
        //     find out the `factorial(n - 1)` again, but this time the 
        //     `n` is actually `(n - 1)` :)
        // So this way, you are digging into the call stack.
        // At some point you reach the 1. WHICH RETURNS 1. WOOHOO.
        // No need to calculate the `factorial` anymore.
        // Now all the expressions you couldn't evaluate, get evaluated 1 by 1
    }