Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК ОАиП.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.14 Mб
Скачать

10. Организация программ с использованием рекурсий

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

В качестве примера дадим рекурсивное определение суммы первых n натуральных чисел. Сумма первых n натуральных чисел равна сумме первых (n - 1) натуральных чисел плюс п, а сумма первого числа равна 1.

Или: Sn= Sn-1 + n; S1 = 1.

Задача 1

Вычислить сумму первых n натуральных чисел, исполь­зуя рекурсию.

Program Lab10_1;

Uses Crt;

Var n: Integer;

S: Integer;

{Описание функции вычисления суммы ряда}

Function Sum (k: Integer): Integer;

Begin

If k=l Then Sum: = 1 {Стоп-условие }

Else Sum: = Sum (k - 1) + k;

End;

{Исполнимая часть головной программы}

Begin

ClrScr;

WriteLn ('Введи количество членов ряда n');

ReadLn (n);

S: = Sum (n);

WriteLn ('Сумма S =’, S: 5);

ReadKey;

End.

Протокол работы программы:

Введи количество членов ряда n 10

Сумма S = 55

Опишем работу программы. Операция суммирования бу­дет повторяться ровно п - 1 раз, поскольку функция Sum об­ращается п- 1 раз к самой себе, при этом параметр каждый раз уменьшается на единицу. В конце концов параметр станет рав­ным 1, и рекурсивные вызовы закончатся, после чего все уже вызванные функции одна за другой завершат свою работу.

Обратим внимание на следующие обстоятельства. Во-первых, рекурсивная процедура или функция содержит все­гда, по крайней мере, одну терминальную ветвь и условие окончания (If n = 1 Then Sum = 1). Во-вторых, при выполне­нии рекурсивной ветви (Else Sum: = Sum (n - 1) + n) процесс выполнения подпрограммы приостанавливается, но его пе­ременные не удаляются из стека. Происходит новый вызов подпрограммы.

Задача 2

Составить рекурсивную функцию Factorial для вычисле­ния факториала числа n (n! = 1 * 2 * 3 ... * n, 0! = 1, 1! = 1), которая основывается на многоразовом (рекурсивном) ис­пользовании формулы n! = n * (n - 1)!.

Program Lab10_2;

Uses Crt;

Var k: Integer;

F: Integer;

{Описание функции вычисления факториала}

Function Factorial (N: Integer): Integer;

Begin

If N = 0 Then Fact: = 1 {Это стоп - условие}

Else Fact: = N* Fact (N - 1);

End;

{Исполнимая часть головной программы}

Begin

ClrScr;

Write ('Введи количество k');

ReadLn (k);

F: = Factorial (k);

WriteLn ('F =*, F: 5);

ReadKey;

End.

1. Особенности рекурсии

  • рекурсивная форма организации алгоритма обычно выглядит изящнее итерационной и дает более компактный текст программы;

  • если глубина рекурсии очень велика, то это может привести к переполнению стека;

  • рекурсивные алгоритмы, как правило, выполняются более медленно;

  • при рекурсивном программировании велика вероят­ность ошибок зацикливания.

В целях повышения безопасно­сти работы рекомендуется:

  • использовать директиву компилятора {$s+} для вклю­чения проверки переполнения стека;

  • использовать директиву компилятора {$R+} для вктючения проверки диапазона.

11. Решение задач на обработку элементов одномерного массива

Задача 1

Рассмотрим примеры описания массивов с пояснениями:

Program Lab11_l;

Const

Start = 100;

Finish = 105;

Var

S : Integer;

A1: Array [1..10] Of Integer;

{массив десяти переменных типа Integer, для доступа будут использоваться индексы 1, 2, 3, 4, 5, 6, 7, 8, 9 и 10. Имя мас­сива – А1 }

А2: Array [5..10] Of Real;

{массив шести переменных типа Real, для доступа будут ис­пользоваться индексы 5, 6, 7, 8, 9 и 10. Имя массива – А2 }

Names: Array [5..10] Of String;

{массив шести переменных типа String, для доступа будут ис­пользоваться индексы 5,6,7,8,9 и 10. Имя массива - Names }

Sprites: Array [0..99] Of Pointer;

{массив ста переменных типа Pointer, диапазон индексов - от 0 до 99. Имя массива - Sprites }

В: Array [Start..Finish] Of Byte;

{массив шести переменных типа Byte, диапазон индексов за­дается константами Start и Finish - от 100 до 105. Имя мас­сива - В }

Bl: Array [Start.. 110] Of Byte;

{массив одиннадцати переменных типа Byte, диапазон ин­дексов задается константами Start и 110 - от 100 до 110. Имя массива - В1 }

IC1: Array [Start..90] Of Byte;

{некорректное описание массива: нижний индекс (задан кон­стантой Start = 100) превышает верхний индекс (задан кон­стантой 90) }

IC2: Array [S..800] Of Byte;

{некорректное описание массива: верхний индекс задан пе­ременной, а не константой }

IC3: Array [1..80000] Of Integer;

{некорректное описание массива: объем оперативной памяти, необходимый для хранения такого массива - 160 000 байт (один элемент типа Integer занимает 2 байта), что превышает максимально допустимый объем}

Begin

{Тело программы}

End.

Задача 2

Рассмотрим пример заполнения элементов массива с помощью операто­ра присваивания и вывод без использования оператора цикла For.

Program Lab11_2;

Var

A : Array [1..3] Of Integer;

A[l]: = 8;

A[2]: = 12;

A[3]: = A[1] + A[2];

WriteLn(‘Первый:’, A[l]);

WriteLn(‘Второй’, A[2]);

WriteLn(‘Tретий:’, A[3]);

End.

Пояснения к задаче 2

Массив А содержит 3 элемента типа Integer. Размерность массива задана явно в описании массива. Изменение значений элементов массива происхо­дит с помощью оператора присваивания. Результат работы программы мы видим в табл. 8.

Таблица 8

A[1] – первый элемент массива

A[2] – второй элемент массива

А[3] – третий элемент массива

8

12

20

Задача 3

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

Program Lab11_3;

Const

n = 9;

Var

A : Array [l..n] Of Integer;

I: Integer;

BEGIN {1}

For i: = 1 To n Do

A[i]: = I*i;

WriteLn;

For I : = 1 To n Do

Begin {2}

WriteLn (i, '-й элемент');

WriteLn (A[i]);

End; {2}

End. {1}

Пояснения к задаче 3

Массив А содержит n элементов типа Integer. Размерность массива зада­на равной 9 в операторе Const перед описанием массива.

Изменение значений элементов массива происходит с помощью операто­ра присваивания в цикле с изменением счетчика i последовательно от 1 до 9. На каждом шаге цикла элементу массива с номером i присваивается значение i * i, т.е. квадрат его индекса.

Вывод результата происходит с помощью второго цикла for. На каждом шаге цикла производится вывод значения элемента массива с индексом i.

Результатом работы программы будет столбик чисел, представляющих собой квадраты чисел от 1 до 10, т. е.: 1, 4, 9, 16,..., 81 с соответствующими пояснениями, какой именно элемент массива выводится.

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