[英]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 << " ";
}
}
我试过这段代码,但每次都打印 1; 我希望我的代码打印它被调用了多少次。
steps
是funct
中的局部变量,每次调用funct
都有自己的副本。 您需要通过对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";
}
就目前而言,您的 function 中的steps
变量是一个自动存储持续时间的局部变量。 后者意味着它将在每次调用 function 时重新初始化为零。
您可以将static
关键字添加到声明中,以便仅在第一次调用 function ( cppreference ) 时进行初始化(为零),并且从那时起,修改后的值将在 function 的后续调用中保持不变(直到或除非它被明确重置1 )。
然而,即便如此,如果您想查看“滚动”计数,您需要在进行任何递归调用之前放置cout
行(报告值的位置)。
这是一种可能性(我还将您的测试条件从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实现此“显式”重置的一种方法是在递归链完成时在else
块中执行此操作。 以下代码展示了如何执行此操作,以及一个简短的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:
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
另一种方法是使用“特殊”值(例如负数)来更改 function 的行为,这样,如果传递了这样的值,function 会将steps
重置为零,然后立即返回。
让 function 返回它被调用了多少次。 这总是比递归调用报告的调用次数多一个:
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.