C++ C++;递归问题
问这个我觉得有点傻,但我们走吧 当我试图在下面的网站上学习递归示例时,我遇到了一个让我困惑的路障 我稍微修改了代码,只是为了了解递归示例中的代码,我几乎完全了解它,但我不明白为什么变量“n”在“Pass B”中递增,而我没有告诉程序递增“n” 你能帮我解释一下吗C++ C++;递归问题,c++,recursion,C++,Recursion,问这个我觉得有点傻,但我们走吧 当我试图在下面的网站上学习递归示例时,我遇到了一个让我困惑的路障 我稍微修改了代码,只是为了了解递归示例中的代码,我几乎完全了解它,但我不明白为什么变量“n”在“Pass B”中递增,而我没有告诉程序递增“n” 你能帮我解释一下吗 #include <stdlib.h> #include <iostream> using namespace std; long factorial (long n) { if (n > 1) {
#include <stdlib.h>
#include <iostream>
using namespace std;
long factorial (long n)
{
if (n > 1)
{
long r(0);
cout << "Pass A" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << endl;
r = n * factorial (n-1);
cout << "Pass B" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << endl;
return (r);
}
else
return (1);
}
int main ()
{
long number;
cout << "Please type a number: ";
cin >> number;
cout << number << "! = " << factorial (number) << endl;
system ("pause");
return 0;
}
#包括
#包括
使用名称空间std;
长阶乘(长n)
{
如果(n>1)
{
长r(0);
您是否可以按顺序看到所有“通过A”-s,然后按相反顺序看到所有“通过B”-s,这给人的印象是,即使您只看到最初通过的n,n也会增加。在我看来,您的程序工作正常,并且应该为数字=3输出类似的内容(为了可读性,请删除换行符):
通过A n=3 r=0[1]
通过A n=2 r=0[2]
通过B n=2 r=2[3]
通过B n=3 r=6[4]
所以我想我可以看到你们如何得出结论,在过程B中,n在增加,但事实并非如此。
您需要记住,n是一个函数局部变量,因此在这种情况下,在[3]中打印的n与[4]中的n是局部变量的不同实例
[1]和[4]中打印的n值来自函数的顶部调用(其中n=3),[2]和[3]中打印的值是因子的顶部版本(即n-1)中的调用。如果您注意到,Pass B并不是第二次真正通过函数,它只打印递归的结果
factorial(3)
factorial(2)
factorial(1) // returns 1
factorial(2) // r=2*1
factorial(3) // r=3*2
因此,A打印4、3、2等,而背景词B打印432 1(即234)
尝试将第二个r打印替换为
cout << "Pass B" << endl;
cout << "n = " << n << endl;
cout << "r = " << r << " --- NOTICE RESULT ACCUMULATING AS WE UNNEST THE RECURSION" <<endl;
PS C:\temp> .\r.exe 4
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2 --- NOTICE RESULT ACCUMULATING
Pass B
n = 3
r = 6 --- NOTICE RESULT ACCUMULATING
Pass B
n = 4
r = 24 --- NOTICE RESULT ACCUMULATING
4! = 24
Press any key to continue . . .
cout这是因为您正在展开递归。
您并不是真正地递增n
您只是返回到上一个函数调用,其中n
在调用factorial(n-1)
之前是n+1
你一开始就去
r = n * factorial (n-1);
这将导致对阶乘的另一个函数调用
您一直这样做(从函数的开头开始,直到调用factorial
,并将n
递减1),直到您最终在调用factorial
的函数中结束,其中n在“展开”递归时会打印Pass B。它会递归,直到到达“else return(1)”部分,然后开始退出。因为它在每次进入的过程中用一个小于n的值调用自己,所以它似乎随着退出而递增。在passA
和passB
中的n
的值将始终与您在其间的任何地方都不更改它的值相同。您将n-1传递给递归调用,但是不会更改n的值
您可能感到困惑的原因是,对于给定的n(n>2)
,您没有看到passA
和passB
When n=2, you'll see:
pass A for n=2
pass B for n=2
When n=3, you'll see:
pass A for n=3
pass A for n=2 // cuz of recursive call.
pass B for n=2
pass B for n=3 // looks like n has increment here..but this 'pass B' pairs with first pass A
因为那是递归倒转的时候
当n
为2时,可能更容易考虑这种情况。在这种情况下,输入条件块并在“Pass A”之后递归。当您递归时,n
为1,因此您通过else
块返回。当您返回时,您返回到递归的前一帧,其中n
为2。r
根据递归调用的结果更新,2*1
,但n
仍保持2
e
factorial(2)
factorial(1)
factorial(2)
如果n
最初是任何较大的值,那么您将继续倒带,并且n
会将其值恢复到每次递归之前的每个值
factorial(3)
factorial(2)
factorial(1) // returns 1
factorial(2) // r=2*1
factorial(3) // r=3*2
一些答案使用缩进使其更容易理解发生了什么-您可以使用相同的效果使自己的调试输出更易于理解:
尝试将您的函数更改为以下内容:
long factorial (long n, std::string prefix= "") // default parameter
...
cout prefix << "Pass A" << endl;
cout prefix << "n = " << n << endl;
cout prefix << "r = " << r << endl;
r = n * factorial (n-1, prefix+ " "); // increase indentation
...etc...
你确定你混淆了对factorial
的不同级别递归调用的输出吗?请注意,对于给定级别的Pass B
会在它引起的所有递归调用Pass B
之后打印出来。这正是问题的类型。不要因为发布它而感到愚蠢。否则会怎样你学会了吗?
long factorial (long n, std::string prefix= "") // default parameter
...
cout prefix << "Pass A" << endl;
cout prefix << "n = " << n << endl;
cout prefix << "r = " << r << endl;
r = n * factorial (n-1, prefix+ " "); // increase indentation
...etc...
Please type a number: 4
Pass A
n = 4
r = 0
Pass A
n = 3
r = 0
Pass A
n = 2
r = 0
Pass B
n = 2
r = 2
Pass B
n = 3
r = 6
Pass B
n = 4
r = 24
4! = 24