这是我的代码:
#include <iostream>
using namespace std;
int factorialFinder(int x){
if (x==1){
return 1;
}else{
return x*factorialFinder(x-1);
}
}
int main()
{
cout << factorialFinder(5) << endl;
}
我目前很难确切了解程序如何使5 * 4 * 3 * 2 * 1 = 120
对我来说,如果我们采用程序的每一行,它就会做到:
5*factorialFinder(5-1) is 5*4
4*factorialFinder(4-1) is 4*3
3*factorialFinder(3-1) is 3*2
2*factorialFinder(2-1) is 2*1
so 5*4*4*3*3*2*2*1 = 2880
对不起,我感到愚蠢,我试图等待几天,然后再考虑一下。 我是C ++的初学者。 它和调用栈有关系吗?
就像我也在考虑这个一样:
原始功能make:
5*4 = 20 20 is the returned value
4*3 = 12 12 is the returned value
3*2 = 6 6 is the returned value
2*1 = 2 2 is the returned value
1*1 = 1 STOP BECAUSE x == 1
弹出调用堆栈
1*1=1 1 is the returned value
2*1=2 2 is the returned value
3*2=6 6 is the returned value
4*6=24 24 is the returned value
5*24=120 120 is the returned value
如果有人能确切解释我的功能,我会很高兴...
非常感谢您的帮助。
答案 0 :(得分:2)
您的推理有缺陷。
5*factorialFinder(5-1) is 5*4
不是,不是。扩展函数调用时,还必须递归执行。递归规则是
factorialFinder(x) == x * factorialFinder(x-1)
说服自己这是正确的。然后将其应用于您的示例:
5*factorialFinder(5-1) == 5* 4*factorialFinder(4-1)
== 5*4* 3*factorialFinder(3-1)
== 5*4*3* 2*factorialFinder(2-1)
== 5*4*3*2*1
答案 1 :(得分:1)
使用等效定义只是打印而不是计算:
#include <iostream>
using namespace std;
void factorialFinder(int x){
if (x==1){
cout << 1;
} else {
factorialFinder(x-1);
cout << " * " << x;
}
}
int main()
{
factorialFinder(5);
cout << endl;
}
执行:
1 * 2 * 3 * 4 * 5
或
#include <iostream>
using namespace std;
void factorialFinder(int x){
if (x==1){
cout << 1;
} else {
cout << x << " * ";
factorialFinder(x-1);
}
}
int main()
{
factorialFinder(5);
cout << endl;
}
执行:
5 * 4 * 3 * 2 * 1
或者,如果您希望查看全部内容:
#include <iostream>
using namespace std;
int factorialFinder(int x) {
cout << "fact(" << x << ") = ";
if (x==1){
cout << 1;
return 1;
} else {
cout << x << " * (";
int v = factorialFinder(x-1);
cout << ") = " << x << "*" << v << " = " << x*v;
return x*v;
}
}
int main()
{
factorialFinder(5);
cout << endl;
}
执行:
fact(5) = 5 * (fact(4) = 4 * (fact(3) = 3 * (fact(2) = 2 * (fact(1) = 1) = 2*1 = 2) = 3*2 = 6) = 4*6 = 24) = 5*24 = 120
答案 2 :(得分:0)
很久以前,这对我有所帮助。
这是传统的非递归阶乘函数
int trad_fact(int n)
{
int res = 1;
for (int i = 2; i <= n; ++i)
res *= n;
return res;
}
现在是我们第一次尝试编写可恢复的阶乘函数
int recur_fact(int n)
{
return trad_fact(n);
}
不是很好,它甚至不是递归的,它所做的只是使用我们已经编写的trad_fact
函数。但我希望您同意,它将给出正确的结果(假设trad_fact
确实如此)。
现在让我们在1
中做一个特例。
int recur_fact(int n)
{
if (n == 1)
return 1;
else
return trad_fact(n);
}
更好的是,除trad_fact
以外,我们仍然对每种情况都使用1
,并且仍然没有递归,但仍然返回正确的结果。
这是另一个变化,这次我们将在recur_fact
中进行第一个乘法,但在其余的计算中使用trad_fact
int recur_fact(int n)
{
if (n == 1)
return 1;
else
return n * trad_fact(n - 1);
}
现在recur_fact
比以前做的工作要多一些,例如recur_fact(5) ==> 5 * trad_fact(4) ==> 5 * 24 ==> 120
,这是正确的答案,但是仍然没有递归。
现在考虑一下。我们有两个函数trad_fact
和recur_fact
,它们都可以计算阶乘,它们以不同的方式执行,但是在给定相同参数的情况下,它们都将返回相同的结果。换句话说,功能是等效的。现在,如果它们相等,那么您会在任何看到使用一个功能的地方都可以替换另一个功能,并且程序不会更改。这甚至适用于recur_fact
函数!所以我们可以做到
int recur_fact(int n)
{
if (n == 1)
return 1;
else
return n * recur_fact(n - 1);
} ^^^^^^^^^^
好像魔术一样,我们突然有了一个递归函数。而且我们已经证明这是正确的每一步!
答案 3 :(得分:0)
正如这里每个人所说的,为什么要假设
5*factorialFinder(5-1) is 5*4
递归是一种动态编程技术。因此,这里,factorialFinder(4)方法调用返回的值将被替换。堆栈跟踪不只是 5 * 4 ,而是像这样反转:
factorialFinder(5) = 5 * factorialFinder(5-1) = 5 * factorialFinder(4)
现在您需要找到factorialFinder(4):
factorialFinder(4) = 4 * factorialFinder(3)
factorialFinder(3) = 3 * factorialFinder(2)
factorialFinder(2) = 2 * factorialFinder(1)
factorialFinder(1) = 1
现在我们有了一个值,可以返回到被调用的函数factorialFinder(2)):
factorialFinder(2) = 2 * factorialFinder(1) = 2*1 = 2
factorialFinder(2) = 2
所以让我们解决factorialFinder(3)等问题
factorialFinder(5) = 5 * factorialFinder(4)
factorialFinder(4) = 4 * factorialFinder(3)
factorialFinder(3) = 3 * 2 = 6
factorialFinder(2) = 2
返还一项:
factorialFinder(5) = 5 * factorialFinder(4)
factorialFinder(4) = 4 * 6 = 24
factorialFinder(3) = 6
factorialFinder(2) = 2
将factorialFinder(4)= 24替换为factorialFinder(5)可解决以下功能:
factorialFinder(5) = 5 * 24 = 120
factorialFinder(4) = 24
factorialFinder(3) = 6
factorialFinder(2) = 2
现在您得到的结果为
factorialFinder(5) = 120
进行递归时,请记住,只有当您拥有一个值而不是一个函数/等式时,才必须进行反向查找。
答案 4 :(得分:0)
递归的关键是理解递归。在这种情况下,您知道5!是
5*4*3*2*1
递归AHA!突然注意到这与
相同5 * (4*3*2*1) = 5 * 4!
因此,您可以注意到4! = 4 * 3!和3! = 3 * 2!然后可以制作通用公式
n! = n * (n-1)!
以1开始!定义为1
这种一般情况完全在您的程序中建模。
return x*factorialFinder(x-1);
基本情况由
处理if (x==1) return 1;