【问题标题】:How to print a recursive trace (factorial function)?如何打印递归轨迹(阶乘函数)?
【发布时间】:2014-02-13 08:00:50
【问题描述】:

为了更好地理解递归,我试图弄清楚如何将递归跟踪记录到控制台。我有“追踪”部分,但我不确定如何“冒泡”解决方案。对完美放置的 console.log 语句有什么建议吗?

这是我目前所得到的:

function factorial (num) {
    if (num === 1) {
        console.log('factorial(' + num + ') = ' + num);
        return 1;
    } else {
        console.log('factorial(' + num + ') = ' + num + ' * ' + 'factorial(' + (num - 1) + ')');
        return num * factorial(num - 1);
    }
}

将以下内容打印到控制台:

factorial(5) = 5 * factorial(4)
factorial(4) = 4 * factorial(3)
factorial(3) = 3 * factorial(2)
factorial(2) = 2 * factorial(1)
factorial(1) = 1
120

但是 1 * 2 * 3 * 4 * 5 部分呢?我知道它发生在某处,我该如何打印它?

我想我希望它看起来像这样:

1
1 * 2
2 * 3
6 * 4
24 * 5
120

感谢您的任何建议!

好的,经过更多搜索,我在CodeRanch 找到了这个,不幸的是没有代码(并且是用 Java 编写的):

Enter fact(6)  
    Enter fact(5)  
        Enter fact(4)  
            Enter fact(3)  
                Enter fact(2)  
                    Enter fact(1)  
                        Enter fact(0)  
                        0!Ret: 1  
                    Ret: 1 * fact(n-1) = 1 * fact(0) = 1 * 1 = 1  
                Ret: 2 * fact(n-1) = 2 * fact(1) = 2 * 1 = 2  
            Ret: 3 * fact(n-1) = 3 * fact(2) = 3 * 2 = 6  
        Ret: 4 * fact(n-1) = 4 * fact(3) = 4 * 6 = 24  
    Ret: 5 * fact(n-1) = 5 * fact(4) = 5 * 24 = 120  
Ret: 6 * fact(n-1) = 6 * fact(5) = 6 * 120 = 720  
fact(6) = 720  

很酷,对吧?经过更多的实验,我仍然无法做到这一点......

【问题讨论】:

  • 您能发布一个您期望的输出示例吗?您也可以简单地从语句中注销阶乘。
  • 刚刚添加了我的预期输出:)
  • 找到我已经提到的答案。它应该可以工作。

标签: javascript recursion


【解决方案1】:
function factorial (num) {
    if (num === 1) {
        console.log(num); //print new line after this
        return 1;
    } else {
        var val = factorial(num - 1);
        console.log(num +'*' + val);  //print new line after this
        return num * val;
    }
}

【讨论】:

  • 这绝对是越来越近了!但我想捕获整个跟踪,而不仅仅是最后一个......
【解决方案2】:

我认为最好使用带有 cmets 的示例(稍作编辑)来解释。假设您第一次调用此函数时将参数设置为 5

// num = 5, the first time it's called
function factorial (num) {
    console.log('factorial(' + num + ')');

    if (num === 1) {
        // If num === 1, the function will just return 1 and exit.
        return 1;
    } else {
        // Otherwise, which happens almost every time (since 1 is only
        // reached once and then it stops). For 5, this would return
        // 5 * factorial(4), which in order returns 4 * factorial(3),
        // and so on.
        return num * factorial(num - 1);
    }
}

此输出可能有助于您理解:

factorial(5) == (5) * (factorial(4)) // (5) * (4 * 3 * 2 * 1)
factorial(4) == (4) * (factorial(3)) // (4) * (3 * 2 * 1)
factorial(3) == (3) * (factorial(2)) // (3) * (2 * 1)
factorial(2) == (2) * (factorial(1)) // (2) * (1)
factorial(1) == (1)                  // (1)

【讨论】:

  • 也许我还是很困惑……右边的 // 东西 -> 这一切都发生在函数内部,对吧?那么不应该有一种方法可以完全按照您输入的方式记录它吗?
  • @i_made_that 不,不完全是,因为在第一行,我只知道5 并且4 * 3 * 2 * 1 部分是在阶乘(4)中计算的。我将对其进行一些编辑以使其更清晰。
  • 是的,这让我摸不着头脑 :) 当我们到达最后一行时(阶乘(1)== 1),阶乘必须通过嵌套函数将计算值向上传递不是吗?在我想象的世界中,我可以通过巧妙定位的 console.log 来捕捉这一点...
  • @Broxzier 在if 语句中使用条件num <= 1 会更好,因为它允许返回0 的阶乘。
【解决方案3】:
function factorial (num) {
        for (var i=1; i<6-num; i++)
            console.log('    ');
        }
        console.log('Enter fact('+num+')'); //add code to move new line
        if(num==0) {
            for (var i=1; i<6-num; i++)
                console.log('    ');
            }
            console.log('0!Ret: 1 '); // add code to move new line
            return 1;
        } else {
            int val = factorial(num-1);
            for (var i=1; i<6-num; i++)
                console.log('    ');
            }
            console.log('Ret:'+num+ ' * fact(n-1) = ' + num+ ' * fact('+(num-1)+') = '+num+' * ' + val + ' = ' + (num*val) ); // add code to move new line
            return num*val;
        }
    }

【讨论】:

  • 最好将两个答案合二为一。
猜你喜欢
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2017-05-07
相关资源
最近更新 更多