- •Самитов р.К.
- •Рекурсивное программирование
- •Задача: фишку можно продвинуть за один шаг на одну или на две клетки вперед (по линии), сколько существует способов продвижения фишки на n клеток вперед?
- •Базовые функции манипулирования списками таковы, что список хорошо просматривать от начала к концу, а хорошо строить – от конца к началу.
Базовые функции манипулирования списками таковы, что список хорошо просматривать от начала к концу, а хорошо строить – от конца к началу.
Р ассмотрим функцию «Обр(x,y)» - она последовательно переписывает элементы стека-списка x в стек-список y, естественно в y порядок следования переписанных из x элементов получается обращенным.
CDR(x)
x : y:
CONS(CAR(x),y)
x: y:
FUNCTION Обр(x,y:TSpisok):TSpisok;
BEGIN IF EQ(x,NIL) THEN Обр:=y ELSE
Обр:=Обр(CDR(x),CONS(CAR(x),y)) END;
FUNCTION Обратить(L:TSpisok):TSpisok;
BEGIN Обратить:=Обр(L,NIL) END;
Нетрудно оценить размер дерева подзадач для нового алгоритма «Обратить», в итоге получим оценку ~n.
В PROGRAM\RECURS\PRJ10\PRJ10.dpr приведена реализация средств обработки LISP-списков (UNIT1) и приведены обе программы «Обратить». Программа работает в Delphi6 (в Delphi4 какие-то несогласованности с модулем Variants для данных типа Variant).
Задача формирования спискового представления арифметического выражения по тексту входного файла.
Входной список: (((a-b)/c)-(f/(g-h)))
123456789012345678901
|
Стек: |
Выходной список: |
4 |
(((E |
(a) |
6 |
(((E-E |
(b,a) |
7 |
((E |
((-,(a,b))) |
9 |
((E/E |
(c,(-,(a,b))) |
10 |
(E |
((/,((-,(a,b)),c)) |
13 |
(E-(E |
(f,(/,((-,(a,b)),c)) |
16 |
(E-(E/(E |
(g,f,(/,((-,(a,b)),c)) |
18 |
(E-(E/(E-E |
(h,g,f,(/,((-,(a,b)),c)) |
19 |
(E-(E/E |
((-,(g,h)),f,(/,((-,(a,b)),c)) |
20 |
(E-E |
((/,(f,(-,(g,h)))),(/,((-,(a,b)),c)) |
21 |
E |
((-,((/,((-,(a,b)),c),(/,(f,(-,(g,h))))))) |
PROGRAM\RECURS\Prj11\Prj11.dpr – нерекурсивная (стековый алгоритм).
PROGRAM\RECURS\PRJ12\PRJ12.DPR – рекурсивная.
PROGRAM\RECURS\PRJ12B\Prj12.dpr – рекурсивная с предварительным преобразованием входного текста в линейное списковое представление.
(*) Приведенная в PROGRAM\RECURS\PRJ09\PRJ9.dpr программа выводит протокол своей работы. Этот протокол наглядно показывает порядок обхода дерева подзадач в каждом из рассмотренных трех вариантов.