Ошибка «Рекурсивный на всех путях управления» при реализации факториальной функции - PullRequest
4 голосов
/ 14 октября 2010

Для класса у меня есть задание:

Напишите программу на C ++, которая выведет количество различных способов, которыми вы можете выбрать k объекты из набора n объектов (и n, и k должны быть положительными целыми числами). Это число задается следующей формулой:

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

Ваша программа должна использовать две функции возврата значений. Первый должен называться factorial и возвращать n!. Вторая функция должна называться combinations и должна возвращать n!/(k! * (n - k)!). Проверьте вашу программу на различные значения n и k пять раз (цикл с контролем количества).

Я придумал решение:

#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': рекурсивный на всех путях управления, функция вызовет переполнение стека во время выполнения;"

Если кто-то может мне помочь, я работаю над этим около часа и я в тупике!

Ответы [ 6 ]

16 голосов
/ 14 октября 2010

Существует два критических элемента определения рекурсивной функции:

  • рекурсивный вызов самого себя
  • a условие завершения

Вы, кажется, пропустили условие завершения.Как бы factorial() перестала называть себя навсегда?

2 голосов
/ 15 октября 2010

Вы определили рекурсивную функцию (то есть в основном функцию, которая вызывает себя), но вы не определили условие выхода. Вы вызываете factorial снова перед возвратом, поэтому функция никогда не завершится, вызывая себя снова и снова.

Вам нужно добавить туда ветку, т.е.

if (set_number == 0)
{
   return 1;
}
else
   return set_number * factorial(set_number - 1);
1 голос
/ 15 октября 2010

Вам не хватает базового варианта.Факториал должен возвращать 1 для set_number <= 1 </p>

0 голосов
/ 15 октября 2010
int factorial(int set_number)
{   
   return set_number == 1?1:set_number * factorial(set_number - 1);
}
0 голосов
/ 15 октября 2010

Ваша факторная функция не заканчивается на одну, она просто повторяется бесконечно.

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

Ваш стиль кодирования также довольно плохой, он выглядит очень C-like. Нет необходимости определять факториал и комбинацию после main, и вы объявляете все свои переменные вверху, никакие объявления и инициализации не смешиваются?

Кроме того, ваша основная функция на самом деле не выполняет то, о чем говорится в спецификации - вы никогда не инициализировали и не присваивали переменную комбинаций и не называли функцию комбинации, ваши переменные ужасно названы и т. Д. Но это ваша домашняя работа, а не мой.

0 голосов
/ 15 октября 2010

Эта функция приведет к бесконечной рекурсии, потому что она никогда не прекращает вызывать себя

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);
 }
...