简单的因子查找器功能

时间:2019-02-07 11:47:50

标签: c++

这是我的代码:

#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 

如果有人能确切解释我的功能,我会很高兴...

非常感谢您的帮助。

5 个答案:

答案 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_factrecur_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;