Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.10.31;
Скачать: CL | DM;

Вниз

Рекурсия   Найти похожие ветки 

 
Николай Быков ©   (2002-10-11 14:38) [0]

Я понял рекурсию на примере функции по вычислению факториала. Но когда начал решать задачки на использование рекурсии, то у меня ничего не получилось. Не могли бы вы мне объяснить рекурсию не на примере факториала?


 
han_malign ©   (2002-10-11 14:43) [1]

выложи что у тебя не получилось, а тебе объяснят почему, так быстрее поймешь



 
Skier ©   (2002-10-11 14:44) [2]

>Николай Быков
Самое главное в этом деле - должна быть "затычка",
т.е. условие возврата из рекурсии...
Иначе Stack Overflow - гарантируется !


 
qube ©   (2002-10-11 14:45) [3]

Ну, допустим, обход дерева.


type
PMyTreeNode = ^TMyTreeNode;
TMyTreeNode = record
left, right: PMyTreeNode;
data: integer;
end;

procedure PrintTree(Root: TMyTreeNode);
begin
writeln(data);
PrintTree(left^);
PrintTree(right^);
end;


т.е., естественно использовать рекурсию при обработке данных, по природе рекурсивных.


 
Николай Быков ©   (2002-10-11 14:45) [4]

>Николай Быков © (11.10.02 14:38)
> объяснить рекурсию


 
Николай Быков ©   (2002-10-11 14:47) [5]

2 куб
Я с деревьями не знаком. Может по проще
У меня конкретно не олучались задачи:
н член арифметической/геометрической прогрессии, перевод из DEC в BIN


 
Дремучий ©   (2002-10-11 14:48) [6]

1.Возьми деньги в тумбочке
2.Пересчитай, если мало - скажи мне
3.Если ты мне скажешь - я положу деньги в тумбочку
4.Если не скажешь - иди в магазин, купи пива
5.Если денег на пиво не хватает - возьми деньги в тумбочке
cм. п.1.

:))


 
Skier ©   (2002-10-11 14:48) [7]

>Николай Быков


> объяснить рекурсию


Это когда функция вызывает сама себя.
(Проще некуда...)<


 
qube ©   (2002-10-11 14:50) [8]

Ой, соврал.
procedure PrintTree(Root: TMyTreeNode);
begin
if Root = nil then Exit;
writeln(data);
PrintTree(left^);
PrintTree(right^);
end;



 
Alx2 ©   (2002-10-11 14:50) [9]

>Николай Быков © (11.10.02 14:38)

На примере чисел Фибоначчи можно? :)

Рекурсия - косвенный или прямой вызов процедурой или функции самой себя. Например - рисуешь кусты. Из чего это состоит? Схематично - из веток наподобие куриной лапы с большими пальцами врастопырку.
Пишем процедуру, рисующую одну лапу, наклоненную под определенным углом "к горизонту" и расположенной в определенном месте окна. А потом рисуем остальные лапы - для этого достаточно рисующей процедуре вызвать смою себя с другими параметрами для каждого пальца уже нарисованной лапы(параметры скажут процедуре, что лапа должна быть поменьше, расти из пальца предыдущей лапы, наклонена перпендикулярно к пальцу). После отрисовки лапы поменьше произойдет еще один вызов ее из самой себя дл отрисовки еще менньшего пальца и.т.д до определенной "пушистости". Таким образом будет весьма кустистый пейзаж :)


 
Странник ©   (2002-10-11 14:58) [10]

...
при переходе от одной матрицы параметров описывающей "куст" к другой с некоторым коеффициентом получаем т.н. фрактальный морфинг. Примеры фрактального морфинга наблюдаются ежедневно в телевизоре - перетекание одного изображения в другое, самый запоминающийся пример - терминатор из "жидкого" металла в "Терминатор-2" - сплошная рекурсия. ;-)).
При использовании рекурсивных процедур, в обязательном порядке д.б. учтено требование реентерабельности.


 
Николай Быков ©   (2002-10-11 14:59) [11]

Ну вот я честно списал решение задачи на рекурсию

function geompr(b1,q,n:integer):integer;
begin
if n=1 then geompr:=b1
else geompr:=geompr(b1,q,n-1)*q;
end;

вычисляет н член геом прогрессии


 
kaif ©   (2002-10-11 14:59) [12]

Общий принцип рекурсивного вызова в том, что, когда функция вызывает сама себя, образуется как бы еще один ее "экземпляр". На деле сначала создаются все экземляры, а потом это все начинает завершаться. Чтобы не возникло переполнения стека нужно, чтобы вызов происходил при определенном условии:
--------------------
procedure AAA;
begin
AAA;
end; // это будет вечный вызов и переполнение стека.
-----------------------
procedure BBB;
begin
if <условие> then
BBB;
end; // это в принципе можно завершить.
----------------------
Ну и нежелательно, чтобы число экземляров достигало миллионов.
----------------------


 
vuk ©   (2002-10-11 15:05) [13]

to Alx2:
Типичный фрактальный алгоритм. :o)


 
Николай Быков ©   (2002-10-11 15:06) [14]

2 Алкс2
Я не знаю что такое фракталы


 
Alx2 ©   (2002-10-11 15:13) [15]

>vuk © (11.10.02 15:05)
Конечно.
Но зачем же сразу страшными словами? :))


 
vuk ©   (2002-10-11 15:13) [16]

В общем случае фракталы - математические объекты для которых характерно самоподобие. То есть часть объекта подобна объекту целиком. В принципе, визуализированные фрактлы зачастую имеют весьма причудливую форму и при этом задаются весьма простыми законами образования.


 
Николай Быков ©   (2002-10-11 15:14) [17]

А может все таки на простом примере объясните. Я вам даже написал его.


 
han_malign ©   (2002-10-11 15:15) [18]

если на пальцах - более мелкий элемент фрактала повторяет вид большого

\/ \/ \/ \/
\ / \ /
\/ \/
\ /
\ /
\ /
\/


 
Николай Быков ©   (2002-10-11 15:18) [19]

ДА я даже не собираюсь понимать фракталы. Я и так загружен рекурсией, а тут еще и вы. Ну трудно что ли на примере, который я дал объяснить?


 
Johnny Smith ©   (2002-10-11 15:30) [20]


Николай Быков © (11.10.02 15:18)
ДА я даже не собираюсь понимать фракталы. Я и так загружен рекурсией, а тут еще и вы. Ну трудно что ли на примере, который я дал объяснить?

2All
Да, блин! Хватит малыша умными словами пичкать!
Фракталы тут развели, понимаешь! Вы еще ему про гипотермию пениса расскажите. Не знаете, что ли, что последует?
:)))))))


 
Николай Быков ©   (2002-10-11 15:31) [21]

Не надо переходить в треп. Помогите понять рекрсию на написанном мною примере


 
Mike Kouzmine   (2002-10-11 15:33) [22]

Пример некорректен. Изначально. Неверно сделано. Нужен контейнер, т.е. список.
type
PMyTreeNode = ^TMyTreeNode;
TMyTreeNode = record
Вершина : PMyTreeNode;
left, right: PMyTreeNode;
data: integer;
end;


Нужна вершина дерева, то бишь начало списка, он в контейнере.
procedure PrintTree(Root: TMyTreeNode);
procedure Print(R: TMyTreeNode);
begin
if R.Left <> Nil then Print(R.Left);
WriteLn(R.Data);
end;
begin
Print(Root.Вершина);
end;


 
Кулюкин Олег ©   (2002-10-11 15:33) [23]

А Яндекс отказывается искать слово рекурсия???


 
MBo ©   (2002-10-11 15:35) [24]

вынесем b1 и й для простоты во внешние переменные
function g(n:integer):integer;
begin
if n>1 then g:=q*g(n-1)
else
g:=b1;
end;

пусть вызвали с n=3
получается
a) g:=q*g(2) - вызов с n=2
b) g:=q*g(1) - вызов с n=1
c) g:=b1 - стоп, возвращаемся в пред. вызов
b) g:=q*b1 (g, полученное в пред. строке)
a) g:=q*(q*b1) (g, полученное в пред. строке)
все, функция возвращает результат - b1*q^2



 
Mike Kouzmine   (2002-10-11 15:36) [25]

Пардон
procedure PrintTree(Root: TMyTreeNode);
procedure Print(R: TMyTreeNode);
begin
if R.Left <> Nil then
begin
Print(R.Left);
WriteLn(R.Data);
end;
end;
begin
Print(Root.Вершина);
end;



 
Digitman ©   (2002-10-11 15:36) [26]

>Johnny Smith

А далее последует "Эй, пипл, набираю в DiamondSoft учиться рекурсии !"

Подпись : непринятый в DiamondSoft и посему страшно обиженный пипл-item))))


 
Николай Быков ©   (2002-10-11 15:41) [27]

2 МБо
То есть сначала все расписывается в памяти пока не дойдет до условия возврата из функции, а потом с конца к началу все выполняется? Я правильно понял?


 
Alx2 ©   (2002-10-11 15:41) [28]

А вот кустик кому? Кому кустик зелененький? :))


procedure TForm1.FormPaint(Sender: TObject);
Const MaxCount=10;
procedure PaintBush(counter, x1,y1 : Integer; len : double; angle : double=Pi/2);
Var
np : TPoint;
begin
if counter<=0 then exit;
dec(counter);
Canvas.MoveTo(x1,y1);
Canvas.Pen.Color := RGB(0,(MaxCount-counter)*10,0);
np := point(x1+round(len*cos(angle)),y1-round(len*sin(angle)));
Canvas.LineTo(np.X,np.Y);
PaintBush(counter,np.X,np.y, len/(1+random*1.2), angle-Pi/5);
PaintBush(counter,np.X,np.y, len/(1+random*1.2), angle);
PaintBush(counter,np.X,np.y, len/(1+random*1.2), angle+Pi/5);
end;

begin
randomize;
PaintBush(MaxCount,ClientWidth div 2,ClientHeight, ClientHeight div 5);
end;




 
qube ©   (2002-10-11 15:42) [29]

Mike Kouzmine (11.10.02 15:36)
Смотрел-смотрел, так и не понял, что в моем примере (с учетом поправки) неправильно. Нормальное бинарное дерево. Может, объясните?


 
Pumpkin   (2002-10-11 15:47) [30]

Хороший пример рекурсии - это "Как мне найти все файлы на диске?"
Посмотри в ФАК.
Выполнимость условия возврата - конечность глубины вложенности папок на диске.


 
Mike B. ©   (2002-10-11 15:49) [31]

Помогите ему с суицидом - не придется объяснять про рекурсию


 
Mike Kouzmine   (2002-10-11 15:49) [32]

qube © -> У рекурсии должно быть начало и конец, как и у всех нас. Как ты ее определишь? У тебя в получается две ветки, причем каждая имеет свое условия для окончания вызовов. Первое условие - Root.Left = Nil, второе, как ты, наверное догадался Root.Right = Nil. Как ты поступишь?


 
kaif ©   (2002-10-11 15:50) [33]

>Николай Быков © (11.10.02 15:41)
>2 МБо
>То есть сначала все расписывается в памяти пока не дойдет до >условия возврата из функции, а потом с конца к началу все >выполняется? Я правильно понял?
Да, правильно. Рекурсия сначала порождает все экземляры, а потом это все вычисляется в обратном порядке. Вот только я бы еще поставил еще какое-то ограничение, чтобы не было переполнения стека или арифметического переполнения (что в данном случае вероятнее)...



 
RV ©   (2002-10-11 15:52) [34]

function geompr(b1,q,n:integer):integer;
begin
if n=1 then geompr:=b1
else geompr:=geompr(b1,q,n-1)*q;
end;
b[n+1] = b[n]·q
каждый член последовательности (начиная со второго) равен предыдущему, умноженному на одно и то же число (знаменатель прогрессии)

Пусть b1=3 q=2 n=4, т.е. geompr(3,2,4)
4=1? - нет, тогда result=geompr(3,2,3)*4
3=1? - нет, тогда result=geompr(3,2,2)*3*4
2=1? - нет, тогда result=geompr(3,2,1)*2*3*4
1=1? - да, тогда result=3*2*3*4



 
qube ©   (2002-10-11 15:53) [35]

qube © (11.10.02 14:50)

Ой, соврал.
procedure PrintTree(Root: TMyTreeNode);
begin
if Root = nil then Exit;
writeln(data);
PrintTree(left^);
PrintTree(right^);
end;



 
Николай Быков ©   (2002-10-11 15:57) [36]

2 РВ
При проверке
> 1=1? - да, тогда result=3*2*3*4

Получается, что geompr присваивается b1, которое равно 3


 
RV ©   (2002-10-11 15:59) [37]

нет, предыдущие накопления тащаться


 
Mike Kouzmine   (2002-10-11 16:00) [38]

qube © (11.10.02 14:50)

Ой, соврал.
procedure PrintTree(Root: TMyTreeNode);
begin
if Root = nil then Exit;
writeln(data);
PrintTree(left^);
PrintTree(right^);
end;
Теперь правильно - сначала печатает себя, потом левую ветку, потом правую.


 
qube ©   (2002-10-11 16:03) [39]

Mike Kouzmine (11.10.02 16:00)
Ну так, чего ж ругаешь? :) Неправильно, изначально. Абыдные слова гаваришь, да?

Поправку-то я раньше внес, чем ты критиковать начал.

Хотя на самом деле неправильно.
writeln(Root.data); //теперь совсем правильно


 
Mike Kouzmine   (2002-10-11 16:08) [40]

Это не суть, важен принцип


 
han_malign ©   (2002-10-11 16:33) [41]

Короче на пальцах про рекурсию

function geompr1(b1,q,n:integer):integer;
begin
if n=1 then geompr1:=b1
else geompr1:=geompr2(b1,q,n-1)*q;
end;
function geompr2(b1,q,n:integer):integer;
begin
if n=1 then geompr2:=b1
else geompr2:=geompr3(b1,q,n-1)*q;
end;
.........................................
function geomprN(b1,q,n:integer):integer;
begin
if n=1 then geomprN:=b1;//однозначно N=n
end;

просто при рекурсии, вместо других экземпляров функции, используется тот же физический фрагмент кода


 
Anatoly Podgoretsky ©   (2002-10-11 16:38) [42]

Хороший пример бесконечной рекурсии это
"У попа была собака ..."


 
Oleg_Gashev ©   (2002-10-11 16:44) [43]

Например:
Дракон Хартера-Хейтуэя

function K(I:Integer):Integer;
begin
if i mod 2=0 then
k:=K(i div 2)
else
K:=i mod 4;
end;

procedure TForm1.FormPaint(Sender: TObject);
var x,y,i,Step,angle:Integer;
begin
Step:=1;
angle:=0;
x:=width div 2;
y:=height div 2;
canvas.Pen.Color:=0;
canvas.MoveTo(x,y);
for i:=1 to 100000000 do
begin
angle:=(angle+K(i)*90) mod 360;
if angle=0 then y:=y-step;
if angle=90 then x:=x-step;
if angle=180 then y:=y+step;
if angle=270 then x:=x+step;
canvas.LineTo(x,y);
end;
end;


 
Alx2 ©   (2002-10-11 16:49) [44]

>Oleg_Gashev © (11.10.02 16:44)
Классика в ход пошла!
Но кусты интереснее :)



Страницы: 1 2 вся ветка

Текущий архив: 2002.10.31;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.017 c
6-101425
Крот
2002-09-02 23:05
2002.10.31
Передача файла с компа на комп.


1-101228
Arhangel
2002-10-21 18:57
2002.10.31
В чем дело не могу понять?:(


3-101103
Nona
2002-10-07 21:12
2002.10.31
Помогите а то я уж запарился!


14-101503
Anatoly Podgoretsky
2002-10-12 08:04
2002.10.31
Именинники 12 октября


14-101467
RV
2002-10-07 11:51
2002.10.31
Почему я не люблю юзеров (повзаимствовано)