- •35 Жегуло а.И. Компьютерные науки 2010-2011 гг. Компьютерные науки Лекции для студентов 1 курса, 2010-2011 уч. Г., семестр 1
- •1. Основные понятия 3
- •2. Введение в язык программирования Pascal 3
- •7. Массивы 16
- •8. Сортировки массивов 22
- •9. Рекурсия 25
- •1. Символьные и строковые типы данных 31
- •Основные понятия
- •Способы описания алгоритма:
- •Введение в язык программирования Pascal
- •Структура программы на языке Pascal
- •Правила записи программ
- •Стиль программирования
- •Переменные и константы. Понятие типа данных
- •Классификация типов данных
- •Стандартные простые типы данных
- •Целые типы
- •Вещественные типы
- •Логические (булевские) типы
- •Перечисляемые типы
- •Интервальные типы
- •Порядковые типы
- •Описание данных
- •Описание переменных
- •Описание констант
- •Описание типизированных констант
- •Выражения
- •Операции отношения
- •Приоритеты операций
- •Арифметические выражения
- •Логические выражения
- •Операторы
- •Оператор присваивания
- •Оператор ввода с клавиатуры
- •Оператор вывода на экран монитора
- •Форматный вывод
- •Условный оператор (оператор альтернативы)
- •Составной оператор
- •Оператор выбора
- •Оператор цикла с предусловием while
- •Оператор цикла с постусловием repeat
- •Оператор цикла for с параметром
- •Вложенные циклы
- •Взаимозаменяемость циклов различных видов
- •Дополнительные конструкции переходов для циклов
- •«Вечные» циклы
- •Простейшие алгоритмы
- •Вычисление суммы и произведения
- •Организация счетчика
- •Нахождение наибольшего и наименьшего значений
- •Рекуррентные последовательности
- •Итерационные алгоритмы
- •Подпрограммы (процедуры и функции)
- •Понятие подпрограммы, ее описания и вызова
- •Цели введения подпрограмм
- •Способы передачи параметров. Виды параметров
- •Параметры-значения
- •Параметры-переменные
- •Параметры-константы
- •Корректность передачи параметров
- •Досрочное завершение работы программы и подпрограммы
- •Реализация вызова подпрограммы
- •Область действия и время жизни идентификаторов
- •Правила видимости
- •Время жизни идентификаторов
- •Побочный эффект функции
- •Массивы
- •Описание переменных-массивов
- •Обозначение элементов массива
- •Двумерные массивы – матрицы
- •Трехмерные массивы
- •Типизированные константы-массивы
- •Операции над массивами
- •Именная эквивалентность типов
- •Передача массива в качестве параметра
- •Открытые массивы
- •Типичные задачи для одномерных массивов
- •Поиск заданного элемента в массиве
- •Анализ методов поиска по количеству операций сравнения
- •Двумерные массивы – матрицы
- •Трехмерные массивы
- •Сортировки массивов
- •Понятие сортировки
- •Параметры оценки алгоритмов
- •Сортировка простым включением (простыми вставками) Принцип сортировки включением
- •Сортировка простым выбором Принцип сортировки выбором
- •Сортировка простым обменом (метод пузырька) Принцип сортировки обменом
- •Сравнение эффективности базовых методов сортировки
- •Использование индексных массивов при сортировке
- •Рекурсия
- •Что такое рекурсия
- •Рекурсивные подпрограммы
- •Прямая и косвенная рекурсия
- •Предварительное (опережающее) описание подпрограммы
- •Опасности рекурсии
- •Бесконечная рекурсия
- •Итерация и рекурсия. Необоснованное применение рекурсии
- •Глубокая рекурсия
- •Когда использовать рекурсию
- •Формы рекурсивных подпрограмм
- •Примеры рекурсивных программ
- •Ввод последовательности целых чисел, заканчивающейся нулем, вывод в обратном порядке
- •Поиск максимального элемента массива
- •Задача о Ханойских башнях
- •Символьные и строковые типы данных
- •Символьные типы данных
- •Представление символов в памяти компьютера
- •Символьные константы и переменные Неименованные символьные константы
- •Стандартные функции над символами
- •Строковые типы данных
- •Строковые типы. Представление строк в памяти компьютера
- •Стандартные функции и процедуры для строк
- •Выделение слов из строки
-
Итерация и рекурсия. Необоснованное применение рекурсии
Итерация – это организация обработки данных с помощью циклов.
Пример: Вычислим число Фибоначчи с заданным номером с помощью цикла и рекурсивно.
f0=f1=1; fn=fn-1+fn-2 при n>1
function Fib(n:integer):; {Циклический вариант вычисления чисел Фибоначчи}
var i,f1,f2,f3: longint;
begin
if (n=1) or (n=2) then Fib:=1
else begin
f1:=1; f2:=1;
for i:=3 to n do
begin f3:=f1+f2;
f1:=f2; f2:=f3
end
Fib:=f3
end;
end;
function RF(n:integer):longint; {Рекурсивный вариант вычисления чисел Фибоначчи}
begin
if (n=1) or (n=2) then RF:=1
else RF:=RF(n-1)+RF(n-2)
end;
Вычислим рекурсивно 5-ое число Фибоначчи.
Сколько рекурсивных вызовов произойдет?
Для вычисления 4-го числа надо вычислить 3-ое и 2-е, для вычисления 3-го – 2-ое и 1-ое, затем повторно вычислить 2-ое; наконец, повторно вычислить 3-е, 2-ое и 1-ое.
Каждый вызов при n>1 приводит к двум дальнейшим вызовам, т.е. число вызовов растет экспоненциально.
Всего будет 8 рекурсивных вызовов. Кроме того, заново вычисляются числа Фибоначчи, которые уже были вычислены.
Вывод: рекурсивная программа вычисления чисел Фибоначчи непригодна для практического использования.
-
Глубокая рекурсия
Если алгоритм достигает слишком большой глубины рекурсии, он может привести к переполнению стека.
Минимизировать использование стека можно за счет уменьшения числа определяемых в подпрограмме переменных, использования глобальных переменных.
Если стек все равно переполняется, перепишите алгоритм в нерекурсивном виде.
-
Когда использовать рекурсию
Рекурсия полезна при решении задач, которые естественным образом разбиваются на несколько подзадач, каждая из которых является более простым случаем исходной задачи.
Но даже если задача определена рекурсивно, не всегда лучшим способом решения задачи является рекурсивный алгоритм. Во многих случаях вместо краткого рекурсивного алгоритма лучше воспользоваться более простой конструкцией – циклом. Хотя программа станет немного длиннее, работать она будет быстрее.
-
Формы рекурсивных подпрограмм
В общем случае любая рекурсивная подпрограмма P включает в себя некоторое множество операторов S и один или несколько условных операторов рекурсивного вызова P. Пока условие истинно, рекурсивный спуск продолжается. Когда условие становится ложным, спуск заканчивается и начинается рекурсивный возврат из всех вызванных на данный момент копий рекурсивной подпрограммы.
Рассмотрим четыре разные формы рекурсивных подпрограмм на примере процедур (для функций аналогично):
-
Действия выполняются до рекурсивного вызова (на рекурсивном спуске).
procedure P; begin S; //выполняется на рекурсивном спуске if условие then Р end;
-
Действия выполняются после рекурсивного вызова (на рекурсивном возврате).
procedure P; begin if условие then P; S; //выполняется на рекурсивном возврате end;
-
Действия выполняются до и после рекурсивного вызова (на рекурсивном спуске и на рекурсивном возврате).
procedure P; begin S1; //выполняется на рекурсивном спуске; if условие then P;
S2; //выполняется на рекурсивном возврате end;
или
procedure P; begin if условие then
begin S1; //выполняется на рекурсивном спуске P; S2 //выполняется на рекурсивном возврате end
end.
-
Каскадная рекурсия – рекурсивные вызовы образуют дерево, например, при рекурсивном вычислении чисел Фибоначчи, при обходе деревьев.
procedure P(n); begin S; //может отсутствовать if условие1 then P(n-1); S1; //может отсутствовать if условие2 then P(n-1); S2 //может отсутствовать
end;