简体   繁体   中英

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; 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. You need to pass a single variable through all calls to funct in order to count correctly.

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. The latter means that it will be re-initialized to zero on each call of the 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 ).

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.

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):

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. 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 :

#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:

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.

Let the function return how many times it has been called. 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";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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