Задания для самостоятельной работы




Рекурсия

Методические указания к лабораторной работе № 8
«Основы алгоритмизации и программирования»

 

Ростов-на-Дону


Составитель: С.В.Шинакова

 

 

Методические указания и задания к выполнению лабораторной работы по теме "Программирование в Delphi: введение Object Pascal" / ДГТУ, Ростов-на-Дону, 2009. ** с.

 

 

Излагаются теоретические и технологические сведения, необходимые для создания консольных приложений в Delphi. Целью работы ставится выработка навыков программирования при помощи современных визуальных средств.

 

Рецензент:

 

Печать оперативная. Формат 60х84/16. Бумага офсетная.

Объем 0,7 усл.-п.л., 0,7 уч.-изд.л.

Тираж ** экз.

__________________________________________________

ã ДГТУ, 2009


Цель работы

Цель работы сводится к изучению рекурсивных подпрограмм. В данной работе рассматривается рекурсия и функции работы с ними.

Рекурсивные подпрограммы

Рекурсивной называется подпрограмма, в которой содержится обращение к самой себе. Такая рекурсия называется прямой. Есть также косвенная рекурсия, когда две или более подпрограмм вызывают друг друга.

При обращении подпрограммы к самой себе происходит то же самое, что и при обращении к любой другой функции или процедуре: в стек записывается адрес возврата, резервируется место под локальные переменные, происходит передача параметров, после чего управление передается первому исполняемому оператору подпрограммы. При повторном вызове этот процесс повторяется. Ясно, что для завершения вычислений каждая рекурсивная подпрограмма должна содержать хотя бы одну нерекурсивную ветвь алгоритма, заканчивающуюся возвратом в вызывающую программу.

При завершении подпрограммы область ее локальных переменных освобождается, а управление передается на оператор, следующий за рекурсивным вызовом.

Простой пример рекурсивной функции — вычисление факториала (это не означает, что факториал следует вычислять именно так). Чтобы получить значение факториала числа n, требуется умножить на n факториал числа
(n-1). Известно также, что 0! = 1 и 1! = 1.

function fact(n: byte): longint:

begin

if (n = 0) or (n = 1) then fact:= 1

else fact:= n * fact(n - 1);

end;

Рассмотрим, что происходит при вызове этой функции при n = 3. В стеке отводится место под параметр n, ему присваивается значение 3, и начинается выполнение функции. Условие в операторе if ложно, поэтому управление передается на ветвь else. Для вычисления выражения n*fact(n-1) требуется повторно вызвать функцию fact. Для этого в стеке отводится новое место под параметр n, ему присваивается значение 2, и выполнение функции начинается сначала. В третий раз функция вызывается со значением параметра, равным 1, и вот тут-то становится истинным выражение (n = 0) оr (n - 1), поэтому происходит возврат из подпрограммы в точку вызова, то есть на выражение n*fact(n-1) для n=2. Результат выражения присваивается имени функции и передается в точку ее вызова, то есть в то же выражение, только теперь происходит обращение к параметру n, равному 3.

Понимание механизма рекурсии помогает осознать ее достоинства, недостатки и область применения.

Рекурсивные подпрограммы чаще всего применяют для компактной записи рекурсивных алгоритмов, а также для работы со структурами данных, описанными рекурсивно, например с двоичными деревьями. Любую рекурсивную функцию можно реализовать без применения рекурсии: для этого программист должен сам обеспечить распределение памяти под необходимое количество копий параметров.

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

При отладке рекурсивных алгоритмов полезно отслеживать глубину рекурсии либо визуально, вставив оператор вывода в начало подпрограммы, либо с помощью типизированной константы, которая увеличивается на единицу при каждом вызове подпрограммы, например:

function fact(n: byte): longint;

const num: word = 0;

begin

inc(num);

writeln(num); { отладочная печать }

if (n = 0) or (n = 1) then fact:= 1

else fact:= n * fact(n - 1);

end;

Напомню, что локальная типизированная константа, в отличие от локальной переменной, размещается в сегменте данных и сохраняет свое значение между вызовами подпрограммы.

В случае переполнения стека программа завершится с соответствующим сообщением об ошибке. Проверка переполнения стека задается ключом компилятора {$S+}. По умолчанию он включен.

Задачи

1. Напишите рекурсивную функцию для нахождения биномиальных коэффициентов (для заданного вычислите все ):

2. Напишите рекурсивную функцию, которая по заданным вещественному x и целому n вычисляет величину xn согласно формуле:

Теоретические вопросы

1. Как называются процедуры или функции, которые вызывают сами себя?

2. Для каких целей создаются рекурсивные алгоритмы?

3. Что называется стеком?

4. Верно ли, что значения всех локальных переменных при очередном вызове рекурсивной процедуры или функции помещаются в стек?

5. В какой последовательности происходит заполнение стека и выбор элементов из стека?

6. Всегда ли в рекурсивном алгоритме должно присутствовать условие выхода из рекурсии?

7. Что произойдет, если рекурсивный алгоритм будет вызывать сам себя «бесконечное» число раз?

8. Верно ли, что решение задачи, реализуемое рекурсивным алгоритмом, можно выразить нерекурсивным алгоритмом?

 

Задания для самостоятельной работы

1. По заданным границам интегрирования а и b вычислите значение определенного интеграла следующего вида:

2. Напишите программу вычисления N-го члена последовательности, начи- нающейся с единицы, в которой: а) каждый следующий член равен сумме обратных величин всех предыду- щих; б) каждый следующий член равен сумме квадратов всех предыдущих;3. Составьте программу вычисления суммы: x^1 x^2 x^3 x^n 1 +- --- +---- + ---- +... + ---- 1! 2! 3! n!4. Составьте программу вычисления суммы: x^1 x^3 x^5 x^7 x^n ---- - ---- + ---- - ---- +... -(-1)^n *---- 1! 3! 5! 7! n! При увеличении n эта сумма приближается к значению sin(x).5. Рекуррентное соотношение x{i-1} a x{i} = ------ + -------, x{1} = 1, a>0 2 2x{i-1} можно использовать для быстрого вычисления квадратного корня из a, так как элементы последовательности при увеличении i очень быстро приближаются к корню из a. Для a=2 начало этой последовательности выглядит так a{1} = 1 a{2} = 1.5 a{3} = 1.4166666667 a{4} = 1.4142156863 a{5} = 1.4142135624 a{6} = 1.4142135624 Составьте программу вычисления квадратного корня.6. Рекуррентное соотношение 2x{i-1} a x{i} = ------- + -----------, x{1} = 1, a>0 3 3x^2{i-1} можно использовать для быстрого вычисления кубического корня из a, так как элементы последовательности при увеличении i очень быстро приближаются к кубическому корню из a. Составьте программу вычисле- ния кубичекого корня из a.7. Определите рекуррентное соотношение и напишите программу определе- ния следующих трёх членов последовательности: а) 1, 2, 6, 24, 120, 720, 5040,... б) 1, 4, 11, 26, 57, 120, 247,... в) 1, 1, 0, -1, 2, -3, 5, -8, 13, -21,...8. Напишите программу определения сопротивления между клеммами А и Б в схеме содержащей n сопротивлений R1. А--|R1|--|--|R1|--|--|R1|--|--|R1|--|--... --|R1|--+ | | | | | --- --- --- --- --- R2 R2 R2 R2 R2 --- --- --- --- --- | | | | | Б--|R3|--|--|R3|--|--|R3|--|--|R3|--|--... --|R3|--+

 

10.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: