简体   繁体   English

如何返回递归function在C++中被调用了多少次?

[英]how to return how many times has a recursive function been called in C++?

void funct(int n)
{
    int steps = 0;
    if(n != 1){
        steps++;
        if((n % 2) == 0){
            funct(n/2);
        }
        else if((n % 2) != 0){
            funct((3*n + 1));
        }
        cout << steps << " ";

    }
    
}

I tried this code, but it prints 1 in every time;我试过这段代码,但每次都打印 1; I want my code to print how many times it has ben called.我希望我的代码打印它被调用了多少次。

steps is a local variable in funct each call to funct has its own copy. stepsfunct中的局部变量,每次调用funct都有自己的副本。 You need to pass a single variable through all calls to funct in order to count correctly.您需要通过对funct的所有调用传递单个变量才能正确计数。

void funct(int n, int& steps)
{
    if(n != 1){
        steps++;
        if((n % 2) == 0){
            funct(n/2, steps);
        }
        else if((n % 2) != 0){
            funct((3*n + 1), steps);
        }
    }
}
int main()
{
   int steps = 0;
   funct(5, steps);
   cout << steps << "\n";
}

As it stands, the steps variable in your function is a local variable of automatic storage duration.就目前而言,您的 function 中的steps变量是一个自动存储持续时间的局部变量。 The latter means that it will be re-initialized to zero on each call of the function.后者意味着它将在每次调用 function 时重新初始化为零。

You can add the static keyword to the declaration to make it so that the initialization (to zero) happens only the first time the function is called ( cppreference ) and, from then on, the modified value will be maintained across subsequent calls of the function (until or unless it is explicitly reset 1 ).您可以将static关键字添加到声明中,以便仅在第一次调用 function ( cppreference ) 时进行初始化(为零),并且从那时起,修改后的值将在 function 的后续调用中保持不变(直到或除非它被明确重置1 )。

However, even with that, if you want to see a 'rolling' count, you will need to put the cout line (where the value is reported) before you make either of the recursive calls.然而,即便如此,如果您想查看“滚动”计数,您需要在进行任何递归调用之前放置cout行(报告值的位置)。

Here is a possibility (I have also changed your test condition from n != 1 to n > 1 , in order to prevent the potential infinite recursion mentioned in the comments to your question):这是一种可能性(我还将您的测试条件从n != 1更改为n > 1 ,以防止在对您的问题的评论中提到的潜在无限递归):

void funct(int n)
{
    static int steps = 0; // Initialized only the first time this line is reached
    if (n > 1) {
        steps++;
        std::cout << steps << " ";
        if ((n % 2) == 0) {
            funct(n / 2);
        }
        else if ((n % 2) != 0) {
            funct((3 * n + 1));
        }
    }
}

1 One way to implement this "explicit" reset would be to do so in an else block, when the recursion chain is complete. 1实现此“显式”重置的一种方法是在递归链完成时在else块中执行此操作。 The following code shows how to do this, along with a short main that shows how the behaviour works on multiple, sequential 'top-level' calls to funct :以下代码展示了如何执行此操作,以及一个简短的main代码,展示了该行为如何在对funct的多个连续“顶级”调用上起作用:

#include <iostream>

void funct(int n)
{
    static int steps = 0;
    if (steps == 0) {
        std::cout << "Top-level call with " << n << "... ";
    }
    if (n > 1) {
        steps++;
        std::cout << steps << " ";
        if ((n % 2) == 0) {
            funct(n / 2);
        }
        else if ((n % 2) != 0) {
            funct((3 * n + 1));
        }
    }
    else {
        std::cout << std::endl;
        steps = 0;
    }
}

int main()
{
    funct(5);
    funct(9);
    funct(8);
    return 0;
}

Output: Output:

Top-level call with 5... 1 2 3 4 5
Top-level call with 9... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Top-level call with 8... 1 2 3

Another way would be to use a 'special' value (like, for example, a negative number) to change the behaviour of the function so that, if such a value is passed, the function resets steps to zero and then returns immediately.另一种方法是使用“特殊”值(例如负数)来更改 function 的行为,这样,如果传递了这样的值,function 会将steps重置为零,然后立即返回。

Let the function return how many times it has been called.让 function 返回它被调用了多少次。 And that is always one more than the number of calls that the recursive invocation reported:这总是比递归调用报告的调用次数多一个:

int funct(int n)
{
    int steps = 0;
    if(n != 1){
        if((n % 2) == 0){
            steps = funct(n/2);
        }
        else {
            steps = funct((3*n + 1));
        }
    }
    return steps + 1;
}

int main()
{
   int steps = funct(5);
   cout << steps << "\n";
}

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

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