Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Object Pascal: кроссплатформенные технологии > Вычисление факториала через рекурсивную процедуру


Автор: Paradise 1.6.2009, 20:04
Уважаемые знатоки, прошу вас подсказать как вычислить факториал через рекурсивную процедуру. Дело в том, что через функцию зделал легко, а на процедуре застрял. Задание такое ничего не могу поделать. Не знаю, либо я тупой, либо препод загнал))

Автор: volvo877 1.6.2009, 20:41
Цитата(Paradise @  1.6.2009,  20:04 Найти цитируемый пост)
Дело в том, что через функцию зделал легко, а на процедуре застрял.
Странно. В принципе без разницы, функция это или процедура:
Код
procedure fact(n: integer; var f: longint);
begin
  if n = 1 then f := 1
  else begin
    fact(n - 1, f);
    f := f * n;
  end;
end;

{ вызов: }
var f: longint;
begin
  fact(6, f);
  writeln(f);
end.


Автор: Paradise 1.6.2009, 21:25
Извините безголового, забыл сказать, что эту процедуру нужно потом использовать в формуле
с = n! / ( m! * ( n - m )! )
Вот на этом я и застрял...

Автор: volvo877 1.6.2009, 22:23
Угу, ты застрял всерьез и надолго... По одной простой причине: процедуру НЕЛЬЗЯ использовать в формуле. Использовать можно только функцию. С помощью процедур можно посчитать значение вот этой формулы, конечно, но для этого тебе понадобится 3 дополнительных переменных... Тебе надо это извращение?

Вызывать - так же, как я показывал, все 3 выражения подряд, потом считать чему равно C:
Код
fact(n, n_f);
fact(m, m_f);
fact(n-m, nm_f);
C := n_f / (m_f * nm_f);

Автор: Paradise 1.6.2009, 22:40
Вот именно, я не мог понять логику препода, сначала я подумал, что он перепутал с функцией, но когда нашел задачу и с фнукцией стал сомневаться в себе т. к. тут легче сделать даже через цыкл)) И это задание на гос екзамен, дурдом))
volvo877, спасибо огромное, вопрос решон  smile 
Прийднться делать через три переменных)

Автор: source777 1.6.2009, 23:01
Цитата(volvo877 @  1.6.2009,  20:41 Найти цитируемый пост)
В принципе без разницы, функция это или процедура
Разница всё же есть, в случае процедуры ты вынужден использовать хвостовую рекурсию, которую компилятор спокойно развернёт в цикл. А в случае функции, далеко не все понимают почему необходимо писать: 
Код

function fact(n: integer; var f: longint): longint;
begin
  if n = 0 then fact:=f
  else begin
    fact(n - 1, f);
    f := f * n;
  end;
end;

function factorial(n: integer)
begin
  factorial:=fact(n, 1);
end;




Цитата(volvo877 @  1.6.2009,  22:23 Найти цитируемый пост)
С помощью процедур можно посчитать значение вот этой формулы, конечно, но для этого тебе понадобится 3 дополнительных переменных... Тебе надо это извращение?
Не обязательно так извращаться, достаточно:
Код

function factorial(n: integer)
var f:longint;
begin
  f:=1;
  fact(n, f);
  factorial:=f;
end;

C := factorial(n)/( factorial(m) *  factorial(n-m) );

Во всяком, случае я бы на месте препода ожидал бы подобного решения и рассказа о том, что такое хвостовая рекурсия и зачем она нужна.



Цитата(Paradise @  1.6.2009,  22:40 Найти цитируемый пост)
И это задание на гос экзамен, дурдом))
Такое простое?  smile Действительно дурдом.

Автор: volvo877 2.6.2009, 09:25
Цитата(source777 @  1.6.2009,  23:01 Найти цитируемый пост)
Не обязательно так извращаться, достаточно:

Вообще-то надо ЧИТАТЬ хотя бы заголовок темы, перед тем, как ответить... Ясно сказано: вычислять факториал через процедуру, с функцией автор сделал самостоятельно...

Цитата(source777 @  1.6.2009,  23:01 Найти цитируемый пост)
в случае процедуры ты вынужден использовать хвостовую рекурсию, которую компилятор спокойно развернёт в цикл
Вынужден? Кем это, интересно? Твоим заявлением? Где ты в коде видел хвостовую рекурсию? Умных слов начитался? Так почитай, хотя бы, что они означают... Во втором посте приведен код (который ты, кстати, скопировал), процедурой вычисляющий факториал безо всякой хвостовой рекурсии... Что я делаю не так?

Автор: source777 2.6.2009, 13:44
Цитата(volvo877 @  2.6.2009,  09:25 Найти цитируемый пост)
Вообще-то надо ЧИТАТЬ хотя бы заголовок темы, перед тем, как ответить...
Что мешает вызывать полученную процедуру из функции? Ничего не мешает!


Цитата(volvo877 @  2.6.2009,  09:25 Найти цитируемый пост)
Вынужден? Кем это, интересно? Твоим заявлением? Где ты в коде видел хвостовую рекурсию?

Вот она:
Цитата(volvo877 @  1.6.2009,  20:41 Найти цитируемый пост)
procedure fact(n: integer; var f: longint);
begin
  if n = 1 then f := 1
  else begin
   fact(n - 1, f);
    f := f * n; // эту строчку можно передвинуть на одну вверх, для чистоты определений, впрочем тут это не суть важно.
  end;
end;



Цитата(volvo877 @  2.6.2009,  09:25 Найти цитируемый пост)
Во втором посте приведен код (который ты, кстати, скопировал), процедурой вычисляющий факториал безо всякой хвостовой рекурсии... Что я делаю не так? 
Всё так, там есть хвостовая рекурсия  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)