【问题标题】:Why does this recursive function work like this?为什么这个递归函数会这样工作?
【发布时间】:2014-09-25 13:25:08
【问题描述】:

我正在尝试学习递归并编写了一个函数,该函数接受一个数字并将其倒数到零,然后再次将其计数到原始数字,该函数有效,但我不明白它为什么有效就像它一样。我理解为什么 else 语句后的第一个打印打印:“5 4 3 2 1”,然后数字为 0,if 语句打印:“0”。在这种情况之后我不明白,因为现在函数在 else 语句之后进入第二个打印并打印:“1 2 3 4 5”,这对我来说很奇怪。如果有人能向我解释这一点,我将不胜感激。

<?php
function rec_downandup($num){
    if($num == 0){
        print '0 ';
    }else{
        print $num.' ';
        rec_downandup($num-1);
        print $num.' ';
    }
}
rec_downandup(5);
?>

输出

5 4 3 2 1 0 1 2 3 4 5

【问题讨论】:

  • 尝试手动跟踪执行。
  • 好吧,5 会通过并打印两次...但在这之间 4 会通过并打印两次...但在这之间 3 会通过并打印两次。 ..等

标签: php algorithm recursion computer-science


【解决方案1】:

当你仔细观察时,它应该会变得清晰。

print $num.' ';
rec_downandup($num-1);
print $num.' ';

对于您的第一个输入,您将获得

print 5.' ';
rec_downandup(4);
print 5.' ';

然后调用它是

print 5.' ';
print 4.' ';
rec_downandup(3);
print 4.' ';
print 5.' ';

所以看起来函数倒数和倒数,但实际上它只是倒数并将每个数字放置两次 - 第二次以相反的顺序,所以它似乎在计数。

【讨论】:

    【解决方案2】:

    @kingero 提供的答案很准确,它准确地解释了正在发生的事情。如果你想直接倒计时,你会这样做 -

    function rec_downandup($num){
        if($num == 0){
            print '0 ';
        }else{
            echo $num;
            $num = rec_downandup($num-1); // you can do this without the variable assignment, it just seems neater this way.
        }
    }
    rec_downandup(5);
    

    【讨论】:

    • 变量赋值在这里对我没有任何意义,该函数甚至不返回任何东西......即使它返回也没关系,因为范围一旦它的作用域就会过期完成
    • 我同意@smerny,这只是一个可读性问题,这就是我评论代码的原因。
    【解决方案3】:

    每次调用re_downandup() 函数时,参数$num 将获取传递给函数的值,并将保留该值直到函数在其最后一个右大括号中结束。

    同样重要的是要理解,在对函数进行递归调用时,执行流程会在此调用中继续,这就是为什么第二个print 不会发生,直到执行从所述递归调用返回。

    让我们来看看:

    print $num.' ';
    rec_downandup($num-1);
    print $num.' ';
    

    第一个print $num 将打印数字,然后执行流程将在对函数的新调用中继续,这将显示变量的值减一。这将继续递归地发生,直到$num 达到零。

    当给定递归中断条件$num == 0时,函数将“被允许”继续执行到结束;所以每个递归调用都会返回,也就是第二个print $num 开始执行的时候,因为当你的程序的执行流程从rec_downandup() 返回时会发生这种情况。

    在这种情况下打印的值将是触发递归调用时$num 变量所具有的任何值。

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      相关资源
      最近更新 更多