Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归阶乘函数如何知道何时停止_Javascript_Algorithm_Recursion - Fatal编程技术网

Javascript 递归阶乘函数如何知道何时停止

Javascript 递归阶乘函数如何知道何时停止,javascript,algorithm,recursion,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;

我试图编写一个递归阶乘函数来练习我的递归,并得出以下结论:

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));
    }
}
函数阶乘(num){
if(num<0){
返回-1;
}else if(num==0){
返回1;
}否则{
返回(num*阶乘(num-1));
}
}
它工作得很好

2个问题

  • 为什么第一个不起作用

  • 第二个人怎么知道什么时候停止跑步。如果num每次实际更改它的值-1,它最终将达到0,它应该触发else If并返回1,但是如果运行factorial(3),它将返回6

  • 递归必须有一个基本情况——函数停止的条件

  • 您将从
    num
    下降到
    num-1
    ,依此类推,直到
    0
    ,此时函数满足基本情况:
    num==0
    ,并返回1。从这一点开始,递归展开,并乘以1*
    num-(num-1)
    num

  • 此外,阶乘仅为非负整数定义,因此返回
    -1
    没有多大意义。另一件事:基本情况应该是
    num==1

    num==1
    时,您要做的是乘以
    1
    ,然后当
    num==0
    时,再乘以
    1
    。它为
    阶乘(0)返回错误的阶乘。

    编辑:阶乘(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
    }
    
    函数阶乘(n){
    //处理棘手的情况:你不妨抛出一个错误
    如果(n<0)返回未定义;
    如果(n==0)返回1;
    //基本情况
    如果(n==1)返回1;
    //迭代步骤
    //(如果函数达到这一点,则表示n>1)
    返回n*阶乘(n-1);
    //为了返回“return”右侧的表达式,
    //您需要计算`阶乘(n-1)`
    //当你尝试计算它时,你会发现,现在你需要
    //再次找出‘阶乘(n-1)’,但这次
    //'n'实际上是`(n-1)`:)
    //这样,您就可以深入调用堆栈。
    //在某个点上,你到达了1。它返回1。呜呜。
    //不再需要计算“阶乘”。
    //现在,所有无法计算的表达式都将按1进行计算
    }
    
  • 递归必须有一个基本情况——函数停止的条件

  • 您将从
    num
    下降到
    num-1
    ,依此类推,直到
    0
    ,此时函数满足基本情况:
    num==0
    ,并返回1。从这一点开始,递归展开,并乘以1*
    num-(num-1)
    num

  • 此外,阶乘仅为非负整数定义,因此返回
    -1
    没有多大意义。另一件事:基本情况应该是
    num==1

    num==1
    时,您要做的是乘以
    1
    ,然后当
    num==0
    时,再乘以
    1
    。它为
    阶乘(0)返回错误的阶乘。

    编辑:阶乘(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
    }
    
    函数阶乘(n){
    //处理棘手的情况:你不妨抛出一个错误
    如果(n<0)返回未定义;
    如果(n==0)返回1;
    //基本情况
    如果(n==1)返回1;
    //迭代步骤
    //(如果函数达到这一点,则表示n>1)
    返回n*阶乘(n-1);
    //为了返回“return”右侧的表达式,
    //您需要计算`阶乘(n-1)`
    //当你尝试计算它时,你会发现,现在你需要
    //再次找出‘阶乘(n-1)’,但这次
    //'n'实际上是`(n-1)`:)
    //这样,您就可以深入调用堆栈。
    //在某个点上,你到达了1。它返回1。呜呜。
    //不再需要计算“阶乘”。
    //现在,所有无法计算的表达式都将按1进行计算
    }
    
    第一个始终调用自身(
    test()
    )-它没有停止的条件。第二个将在
    num===0
    时停止。第二个有一个
    if()
    语句,当它到达基本大小写时不会递归。这就是递归的本质。第二个递归之所以有效,是因为即使它返回1,结果在调用它的函数(其中num=1)中乘以
    num
    ,然后在调用堆栈上乘以2,依此类推。第一个递归总是调用自己(
    test()
    )-它没有停止的条件。第二个将在
    num===0
    时停止。第二个有一个
    if()
    语句,当它到达基本大小写时不会递归。这是递归的本质。第二个函数可以工作,因为即使它返回1,结果在调用它的函数中(其中num=1)乘以
    num
    ,然后再乘以2,依此类推,这是对递归过程的良好描述。谢谢我仍然很难理解,但这是我见过的最好的解释。现在有点道理了。哈哈。我只是需要更多地使用它们,直到它们开始制作sense@nwimmer123我已经更新了一点描述,我希望它更清晰。很好地描述了递归过程。谢谢我还是很难理解,但这是我见过的最好的解释