简体   繁体   English

难以理解连续的递归调用

[英]difficulty in understanding successive recursive calls

I am trying to understand the following program in which successive recursion function calls are present, but getting confused while tracing how the tack gets loaded.我试图理解以下程序,其中存在连续的递归函数调用,但在跟踪如何加载大头针时感到困惑。

void func(char*);  // function prototype

int main(){
    func("123");
    return 0;
}

void func(char a[]){
    if(a[1]=='\0')
        return;
    func(a+1);
    func(a+1);
    printf("%c",a[1]);
}

the output for this is 3 3 2输出为 3 3 2

would appreciate if someone could advise on this one...如果有人可以就此提出建议,将不胜感激...

does this kind of multiple recursive calls beneficial in any way or find application in specific problem areas..?这种多次递归调用是否以任何方式有益或在特定问题领域找到应用..?

Just put yourself in the position of the CPU and step through line-by-line (or use a debugger to help with that task).只需将自己置于 CPU 的位置并逐行执行(或使用调试器来帮助完成该任务)。

The first call is to第一个电话是

func("123")

this call does not satisfy the termination condition a[1] == '\\0' , so it calls此调用不满足终止条件a[1] == '\\0' ,因此它调用

func("23");

The call to func("23") in turn calls对 func("23") 的调用依次调用

func("3")

which DOES satisfy the return condition.满足返回条件。 So, that call returns to the previous caller, func("23").因此,该调用返回到前一个调用方 func("23")。

func("23") proceeds to make another call to func("3") due to the lines由于这些行,func("23") 继续对 func("3") 进行另一个调用

func(a+1);
func(a+1);

Continue this process of executing the program in your mind, and write down what would be in each call to printf .在你的脑海中继续这个执行程序的过程,并写下每次调用printf会发生什么。 That will explain your output.这将解释您的输出。

UPDATE更新

Note that the call to printf() happens after the recursive calls, so eg a call to请注意,对 printf() 的调用发生递归调用之后,例如调用

func("123")功能(“123”)

would proceed like会像

  • Enter func("123")输入 func("123")
  • Termination condition not met不满足终止条件
  • Call func("23")调用 func("23")
  • Call func("23") again再次调用 func("23")
  • Printf("3") (which is a[1]) printf("3")(这是一个[1])
  • Return返回

the posted code is a rather poorly designed instance of recursion.发布的代码是一个设计相当糟糕的递归实例。

The following code has the correct 'tail' form of recursion.以下代码具有正确的递归“尾部”形式。

It could be made even better by passing the reversed string back to main and let main print it.通过将反转的字符串传回 main 并让 main 打印它,它可以做得更好。

It reverses the order of the string passed to func() by main()它颠倒了 main() 传递给 func() 的字符串的顺序

Please, when asking about a runtime problem, post code the compiles, including the necessary #includes for header files so we are not guessing about which headers to include请在询问运行时问题时,发布编译代码,包括头文件所需的 #includes,这样我们就不会猜测要包含哪些头文件

#include <stdio.h>

void func(char*);  // function prototype

int main(){
    func("123");
    return 0;
}

void func(char a[])
{
    if(a[1]=='\0')   // check for end of recursive sequence
    {
        printf( "%c", a[0] ); // last tail action
        return;
    }

    func(a+1);    // step+next recursion
    printf( "%c", a[0] ); // tail action
    return;
}

Debugging with breakpoints is one way to understand recursion.使用断点调试是理解递归的一种方式。 Another way is to draw the tree of recursive calls.另一种方法是绘制递归调用树。

递归调用树

From the figure, In every level after level0, the printf statement occurs after every two nodes owing to these two lines of code:从图中可以看出,在level0之后的每一层中,由于这两行代码,printf语句出现在每两个节点之后:

func(a+1);
func(a+1);

In general, this becomes a perfect binary tree for any input string of length greater than 0. The total number of nodes is given by this formula:一般来说,对于任何长度大于 0 的输入字符串,这都会变成一个完美的二叉树。 节点总数由以下公式给出:

2^(k+1) - 1 // k is the depth; here k = 2

Total number of printf statements executed can be obtained by this formula:执行的printf语句总数可以通过这个公式得到:

2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively

The recursion can be simply understood as follows.递归可以简单理解如下。

For example:例如:

Func(int a){
    while(a>1)
        return a * func(a-1);
}

Suppose a = 5 .假设a = 5

What happens is that it returns 5 * func(4) .发生的情况是它返回5 * func(4)

Now func(4) returns 4 * func(3) and it goes on like this.现在func(4)返回4 * func(3)并且它继续这样。

Check out this example for use of recursion in fibonacci series .查看此示例以了解在斐波那契数列中使用递归

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM