【问题标题】:Why recursion works backwards?为什么递归向后工作?
【发布时间】:2019-08-22 06:56:31
【问题描述】:

我无法理解这种递归的工作原理。 为什么输出显示:C B A 而不是 A B C?

void recur(const char* sth) {

    if (*sth != 'D') {
        recur(sth+1);
        std::cout << *sth << std::endl;
    }
}

int main(){

    recur("ABCD");
}

一开始,我有'ABCD', 然后我用'BCD'递归调用,但同时不应该第一次调用recur函数打印'A'?

在递归调用中,recur函数应该再次递归调用'CD',但也需要第二次调用recur函数打印'B'

等等……

我确信即使函数调用自身,第一次调用也不会自动结束。

我知道你们中的一些人会推荐我使用调试器,但我没有找到任何可以帮助我理解这一点的东西,这就是我决定在这里寻求帮助的原因。

亲切的问候,

【问题讨论】:

  • "我知道你们中的一些人会推荐我使用调试器,但我没有找到任何可以帮助我理解这一点的东西" 请解释一下,如何逐行浏览你的代码,不会帮助你理解这一点?
  • 因为您在打印任何内容之前进行了递归调用——就这么简单。
  • 这是递归的绝妙例子!我们老 C/C++ 程序员把它当作主食,但对于新手来说,它是学习曲线的很大一部分

标签: c++ recursion


【解决方案1】:

第一个元素在所有其他元素之后处理。同样,第二个元素在其后的所有元素之后处理,依此类推。

void recur(const char* sth) {

    if (*sth != 'D') {
        recur(sth+1); // <- Here you are processing the rest...
        std::cout << *sth << std::endl; // <- ... before processing the current
   }
}

尝试翻转这些线条。这也使得这变成了一个尾递归以获得额外的分数。


我确信即使函数调用自身,第一次调用也不会自动结束。

正确,函数必须返回,然后调用者继续。如果没有,那么你不会看到它输出任何东西,因为你是在递归调用之后输出的。

一开始,我有'ABCD',然后我用'BCD'递归调用,但同时不应该第一次调用recur函数打印'A'?

它确实“打印”了“A”。它在递归调用之后执行,该调用正在打印其他所有内容,导致“A”成为最后一个输出。


我看到你说“同时”。递归调用不等待调用者完成或类似的事情。相反,调用者将在递归调用之后恢复。需要明确的是,递归调用完成后,调用之后的代码将继续执行。 使用调试器单步调试代码应该可以清楚地说明这一点。

【讨论】:

  • 嗯...我在调试过程中错过了一个断点,这就是为什么我实际上并没有看到所有重复调用首先结束,然后在终端中打印输出...无论如何你的解释帮助了我,所以谢谢你:)
【解决方案2】:

执行代码的顺序始终很重要。你用“ABCD”调用recur函数,所以:

如果 char 指针不在 'D' 处: -> 再次使用“BCD”调用该函数,然后才有机会输出当前 位置。

只需切换输出和函数调用即可。

【讨论】:

    【解决方案3】:

    在获得所需输出之前,您再次调用该函数。

    因此,当您第一次调用 recur(sth+1) 时,它会进入该函数的下一个“实例”,并且它将继续评估,直到您不满足条件。当它到达最后一次调用时(在这种情况下,当您到达'C' 时),输出将打印在控制台中。然后它继续“向后”,并返回到您到达'B' 的那个调用,然后执行下一行。如果不清楚,也许这个代码解释可能是。

    void recur(const char* sth) { // value of char* sth is "ABCD"
        if (*sth != 'D'){
            recur(sth+1); // this adjusts the pointer, and calls the function
                          // the current function will branch to a new function
            std::cout << *sth << std::endl; // this line will not execute until the
            // last line has been fully evaluated. This remains true for all calls of recur()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 2021-11-03
      • 2014-01-21
      • 2017-09-22
      相关资源
      最近更新 更多