【问题标题】:"Recursive on All Control Paths" error when implementing factorial function实现阶乘函数时出现“在所有控制路径上递归”错误
【发布时间】:2011-04-25 14:52:24
【问题描述】:

对于班级我有一个作业:

编写一个 C++ 程序,该程序将输出您可以从一组 n 对象中选择 k 对象的不同方式的数量(nk 都应该是正整数)。这个数字由以下公式给出:

C(n, k) = n!/(k! * (n - k)!)

您的程序应该使用两个返回值的函数。第一个应称为factorial 并应返回n!。第二个函数应该被称为combinations 并且应该返回n!/(k! * (n - k)!). 测试你的程序五次nk 的不同值(计数控制循环)。

我想出了一个解决方案:

#include <iostream>
using namespace std;
int factorial(int);
int combination(int, int);

void main(void)
{
    int objects, set_number, count; 
    count = 1; 
        while(count <= 5)
        {
            cout << "Please enter in number of objects ";
            cin >> objects; 
            cout << "Please enter in the number of Sets ";
            cin >> set_number;
            count++;
        }

    cout << "The Factorial is " << factorial(set_number) << " & the combination is " << combination << endl;
    cout << endl; 
}

// Factorial 
int factorial(int set_number)
{
    int cal;
    cal = set_number * factorial(set_number - 1);
    return cal; 
}

//  Combination
int combination(int objects, int set_number)
{
    int com_total, cal_set, cal_obj, min_sum, cal_min;

    cal_set = set_number * factorial(set_number - 1);
    cal_obj = objects * factorial(objects - 1);
    
    //n!/(k! * (n - k)!)
    min_sum = set_number - objects; 
    cal_min = min_sum * factorial(min_sum- 1);
    com_total = cal_set / (cal_obj * cal_min);
    return com_total; 
}

...但我不断收到错误消息;

"'factorial' : 在所有控制路径上递归,函数会导致运行时栈溢出;"

如果有人可以帮助我,我已经为此工作了大约一个小时,我被难住了!

【问题讨论】:

  • 现在对于所有已经通过递归实现阶乘的人来说,这是一个简单的代表;)
  • 至少在 Visual Studio 上,默认情况下只是警告,而不是错误。您可以随意忽略它并编译它,尽管该函数会导致运行时堆栈溢出。这是非常相关的;如果您试图理解这样的警告,在递归函数中设置断点并单步执行程序可能会很有指导意义。
  • 问题标题真的很糟糕。这个问题与输出数字关系不大,HELP 很烦人,有点冒犯。我们知道您需要帮助,“帮助!”让你看起来像是对它有某种道德主张(就好像你溺水或其他什么一样)。
  • 大声笑,我会记住这一点,大卫。这对我来说是全新的,什么是合适的名字?
  • @Stephenson024:类似于“递归问题”或“递归警告消息”。您遇到的问题是递归,而不是输出。

标签: c++ recursion stack-overflow compiler-warnings factorial


【解决方案1】:

递归函数定义有两个关键要素:

  • 对自身的递归调用
  • 一个终止条件

您似乎缺少终止条件。 factorial() 怎么会永远不叫自己呢?

【讨论】:

    【解决方案2】:

    您定义了一个递归函数(即基本上是一个调用自身的函数),但您尚未定义退出条件。你在返回之前再次调用factorial,所以函数永远不会结束,一遍又一遍地调用自己。

    你需要在那里添加一个分支,即

    if (set_number == 0)
    {
       return 1;
    }
    else
       return set_number * factorial(set_number - 1);
    

    【讨论】:

      【解决方案3】:

      这个函数会导致不定式递归,因为它永远不会停止调用自己:

      int factorial(int set_number)
      {
          int cal;
          cal = set_number * factorial(set_number - 1);
          return cal; 
      }
      

      这就是你想要的:

      int factorial(int n)
       {
        if (n<=1)
          return(1);
        else
          n=n*factorial(n-1);
          return(n);
       }
      

      【讨论】:

      • 对于这样一个开始的问题,如果您将修复程序尽可能地接近现有代码,那么在 OP 上可能会更容易。此外,return(n); 上的缩进使您的代码难以阅读。
      【解决方案4】:

      您缺少基本情况。对于 set_number ,阶乘应该返回 1

      【讨论】:

        【解决方案5】:

        您的阶乘函数不会终止于一个,它只是无限期地递归。

        int factorial(int set_number)
        {
            if (set_number <= 1)
                return 1;
            return set_number * factorial(set_number - 1);
        }
        

        你的编码风格也很差,看起来很像 C。不需要在main之后定义阶乘和组合,并且在顶部声明所有变量,没有混合声明和初始化?

        此外,您的 main 函数实际上并没有按照规范的要求执行 - 您从未初始化或分配给组合变量,也没有调用组合函数,您的变量命名非常糟糕,等等。但这是您的作业,而不是我的。

        【讨论】:

        • 您的程序有错误。 0! == 1.
        【解决方案6】:
        int factorial(int set_number)
        {   
           return set_number == 1?1:set_number * factorial(set_number - 1);
        }
        

        【讨论】:

          猜你喜欢
          • 2016-11-14
          • 1970-01-01
          • 2023-03-25
          • 2017-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 2019-08-06
          相关资源
          最近更新 更多