Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
рпр.doc
Скачиваний:
3
Добавлен:
22.11.2018
Размер:
328.19 Кб
Скачать

2008 № 5 Информатика

Begin

write ('Введите очередное число

последовательности') ; readln{n); If n <> 0 Then Begin

{Рекурсивно вызываем процедуру Output для ввода очередного числа} Output;

(После 'возвращения' из нее выводим введенное число} write(n, ' '} End Else

write ('Числа последовательности

в обратном порядке: ') End;

20. Задача "Ханойские башни".

Имеется три стержня А, В, С. На стержень А нани­заны п дисков таким образом, что диаметр дисков уве­личивается при их просмотре сверху вниз. Требуется переместить все диски на стержень В, используя диск С как вспомогательный и соблюдая следующие правила:

1) перекладывать диски можно по одному;

2) снятый диск нельзя отложить — он должен быть надет на один из стержней;

3) диски нельзя размещать на дисках меньшего раз­мера.

Решение

Если диск один — задача решается одним переме­щением. Сложнее, если дисков больше. Предположим, что мы умеем перекладывать пирамиду из (п — 1) диска. Тогда для перемещения п дисков необходимо:

1) переместить верхние (п — 1) дисков на стержень С;

2) перенести последний, самый большой, диск со стержня А на стержень В;

3) переместить пирамиду из (п — 1) дисков со стерж­ня С на стержень В.

Решение задачи для (п — 1) дисков аналогично. В ре­зультате таких рекурсивных действий можно прийти к ситуации, когда количество перемещаемых дисков рав­но 1, а такую задачу мы решать умеем.

В программе следует использовать две процедуры, одна из которых — рекурсивная:

1) процедуру перемещения одного диска:

Procedure MoveOneDisk(a, b: char); Begin

Write{a, '->', b, ' ') End;

2) процедуру перемещения п дисков:

Procedure MoveDisks(n: byte; a, b, c: char); Begin

If n = l Then

{Используем процедуру MoveOneDisk} MoveOneDisk(a, b)

Else

Begin

MoveDiskstn - 1, a, c, b); write(a,'->', b, ' '); MoveDisks(n — 1, c, b, a) End End;

Можно также задачу при п = 1 отдельно не рассмат­ривать:

Procedure MoveDiskstn: byte; a, b, с: char); Begin

If n > 0 Then Begin

MoveDisks(n - 1, a, c, b); writeta,'->', b, ' '); MoveDiskstn - 1, c, b, a) End End;

5. Прямая и косвенная рекурсия

Обычная" рекурсия, при которой процедура илр функция обращается к самой себе, называется "прямой рекурсией". Существует также разновидность рекурсии которую называют косвенной, или непрямой. Такой ре-курсией является ситуация, когда процедура А вызыва ет себя в качестве вспомогательной не непосредственно а через другую вспомогательную процедуру Б, которая в свою очередь, обращается к процедуре А.

Косвенную рекурсию демонстрирует следующа* программа, в которой находятся и выводятся вс( простые числа, не превышающие некоторого зна чения п.

Создадим функцию логического типа с именем Prim проверяющую, является ли число i — ее параметр, прос там. Чтобы ответить на этот вопрос, достаточно прове рить делимость г на все простые числа, не превышающе квадратный корень из г. Перебор таких простых чисе можно организовать так: рассмотреть первое просто число — 2, а затем использовать функцию NextPrin, возвращающую следующее за значением ее параметр; простое число:

Function Prim(j: word): boolean;

Var k: word;

Begin

k := 2; (первое простое число} While (k * k <= j) And (j mod k <> 0) Do k := NextPrim(k);

(Значение к 'пробегает' последовательность простых чисел, начиная с 2 и до корня из j, при этом проверяется, делится ли j на одно из таких простых чисел} If j mod k = 0

(Если встретилось составное число} Then Prim : = false Else Prim := true End;

Функцию же NextPrim можно оформить так: Function NextPrim(i: word): word; Var p: word; Begin

p := i + 1;

2008 N. 5 ИНФОРМАТИКА

While notd'iimfp)) Do N"Xt.Pr i m ; - jj

End

И пси потеряются на "простоту" числа/), начиная со шачепии, на I большего шачепин параметра /, и дела­ется .m> с homoiijiiIo функции Prim (т.е. функция Prim нмзмнает функпик> N<:*xr.Pr im, а последняя обращается к I'rim, т.е. имеет место к(Ч*венная рекурсия).

При косвенной рекурсии возникает проблема —■ если нерпой ошютгь функцию Pi im/гоона будет иснольижать еще не описанную функцию N<xt pr im, ччч1 и языке про­граммирования I Ьскаль недопустимо(аналогичнои если, naiWxijxrr, первой описать функцию N>-xt Pr im). Выходом янляето! так na.tbiiviCMiK' "опережаюп^х* описание" функ­ции. Оно лчкакусктся (мим, тл> :к1пхинкж НАШ41 и.ч функ­ций ука «лки-тся пер1*ым со слуиаЧжымслопом For w.i i d:

Function N<'Xt.Prim(i: ward): word; Forward; — после чего полностью описывается сгорая функция:

Function Pr im(j : word): boolean;

Var k: word;

Begin

:i taivM — нерпам функция; Function NextPrim; Var ;: word; Begin

OGpiuijaeM Ш1ил\;и(ие mi ti>, что в полном описи 1ии функ-цииЫехг.Ргхт в лн^ичжесписок 1\юрмяльш>\хпярлмитроа и тип ремулкпгт не ук;иыв:шл\:л (они уже объявлены piuteti).

Замечим также, что число 2 — простое, а число 1 простым не считается. Это означает, что значение 2 в основной программе должно быть вынелено без про­верки, которая ндхшодится с иомопи»к) функции Prim для всех нечетных чисел, не превышающих п.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]