难以理解此递归

Difficulties in understanding this recursion

本文关键字:递归      更新时间:2023-10-16

我在C++没有得到这个递归练习。在这里:

int fatt(int x){
int s=1; // here. since 's' will always be 1 shouldn't i get 1 as an output???
if(x>1) { s = x*fatt(x-1); }
return s;
}
int main()
{
int n;
cout << "Type a number: ";
cin >> n;
if (n < 0) { cout << "Error" << endl; }
if (n <=1) { cout << "Factorial: 1" << endl; }
else { cout << "Factorial: " << fatt(n) << endl; }
}

如果我输入s=0它会返回我作为输出总是0,如果我输入 2,它会使结果加倍 O.o我不明白它是如何工作的。我知道x总是在减少,直到达到 2 并且返回结果,但每次调用函数时,不应该给"s"取值 1???

假设您使用参数值 3 调用函数: 它看起来像这样:

int fatt(3) {
int s = 1;
if (3 > 1) s = 3 * fatt(3 - 1);
return s;
}

所以 s 是计算3 * fatt(2)的结果,fatt(2)的结果是:

int fatt(2) {
int s = 1;
if (2 > 1) s = 2 * fatt(2 - 1);
return s;
}

所以 s 是计算的结果2 * fatt(1)fatt(1)的结果是:

int fatt(1) {
int s = 1;
if (1 > 1) s = 1 * fatt(1 - 1);  // False so this is never executed.
return s;
}

fatt(1)的结果是 1。因此,这就是我们回到fatt(2)的召唤,然后翻译为:

s = 2 * 1;

这给出了结果 2,然后返回到fatt(3)的调用,然后给出:

s = 3 * 2;

这给出了结果 6。

请记住,每次执行函数时,都会将局部变量 s 推送到堆栈上。所以它不是同一个变量。

如果将 s 启动为 2,则第一行将为:s = 2 * 2;,函数的其余部分将给出结果值的两倍。由于s确实是您最终乘以的一个因子,因此在您的阶乘中:

所以顺序:3 * 2 * 1变得3 * 2 * 2.

变量s是函数fatt的给定实例化的局部变量。当函数递归调用自身时,每个调用都会获得自己的新s副本。此值初始化为 1,但不会影响堆栈中所有先前的s实例。然后,在fatt调用乘以其本地x副本后,将其中的每一个都分配给该调用的结果。

's' 应该是 1,但它被赋值,然后在函数完成后更改它所持有的值。

递归一开始可能有点难以理解,但一旦你这样做了,它就很漂亮了。

我建议你用笔和纸。

1) 设 x = 3;

int fatt(3) {
int s = 1;
if (3 > 1) s = 3 * fatt(3 - 1);
return s;} 

2) 在函数中 3>1 = true,所以它再次传递,但这次是 (3-1),即 2

注意:函数未完成执行

3) 现在 x = 2

int fatt(2) {
int s = 1;
if (2 > 1) s = 2 * fatt(2 - 1);
return s;}

4) 重复步骤 2) (2-1) 即 1

5) 由于 x 不是第 3 个函数调用中的 1>,这会导致返回 s

s = 1;
return s;

所以。。。

从第二个函数调用开始:

s = x * fatt(x-1);
s = 2 * 1;
return s;

第一次调用再次重复此操作)

s = x * fatt(x-1);
s = 3 * 2;
return s;

把它想象成一堆函数

第一个堆栈-------调用堆栈 2 并等待

第二个堆栈----------调用堆栈 3 并等待

等待----------的第一个堆栈

最后。。。

未满足条件返回的第 3 个堆栈----------

第 2 个堆栈----------条件完成返回

返回第一个堆栈---------条件完成

希望有帮助