Вы находитесь на странице: 1из 139

Федеральное государственное автономное образовательное учреждение высшего

образования
Северо-Кавказский федеральный университет
Институт информационных технологий и телекоммуникаций

МЕТОДИЧЕСКИЕ УКАЗАНИЯ
ПО ВЫПОЛНЕНИЮ ЛАБОРАТОРНЫХ РАБОТ
по дисциплине «Технологии и методы программирования»
для бакалавров направления 10.03.01 «Информационная безопасность»

Ставрополь 2017 г.
1
УЧЕБНО-МЕТОДИЧЕСКОЕ ПОСОБИЕ
Лабораторный практикум
Технологии и методы программирования

Направление подготовки
10.03.01 – Информационная безопасность

Профиль подготовки
Организация и технология защиты информации

Квалификация (степень) выпускника


Бакалавр

Форма обучения

Очная

Ставрополь 2017

2
Содержание
Содержание ........................................................................................................ 3
Предисловие ....................................................................................................... 5
1-2. ............................................. Технологичность программного обеспечения 7
Методические рекомендации ........................................................................... 7
Модули и их свойства ...................................................................................... 8
Сцепление модулей ........................................................................................ 10
Связность модулей ......................................................................................... 10
Рекомендуемая литература ............................................................................. 12
Задания для развития и контроля владения компетенциями ...................... 12
3-4. ..........................................Проектирование ПО при структурном подходе 15
Методические рекомендации ......................................................................... 15
Структурная схема разрабатываемого программного обеспечения ......... 15
Функциональная схема .................................................................................. 16
Использование метода пошаговой детализации для проектирования
структуры программного обеспечения ........................................................ 18
Рекомендуемая литература ............................................................................. 20
Задания для развития и контроля владения компетенциями ...................... 20
5-6. ......................................................... Фундаментальные структуры данных 21
Методические рекомендации ......................................................................... 21
Общее понятие типа данных ......................................................................... 22
Простой тип .................................................................................................... 23
Строковый тип ................................................................................................ 26
Структурные типы.......................................................................................... 26
Записи .............................................................................................................. 28
Множества....................................................................................................... 29
Представление структур в памяти ................................................................ 30
Рекомендуемая литература ............................................................................. 32
Задания для развития и контроля владения компетенциями ...................... 33
7-8. ................................................. Простейшие методы сортировки массивов 34
Методические рекомендации ......................................................................... 34
Оценка алгоритмов сортировки .................................................................... 34
Сортировка простым обменом (пузырьковый метод) ................................ 35
Шейкер-сортировка ........................................................................................ 35
Сортировка простым выбором ...................................................................... 36
Сортировка простыми вставками ................................................................. 37
Сортировка бинарными вставками............................................................... 38
Рекомендуемая литература ............................................................................. 38
Задания для развития и контроля владения компетенциями ...................... 39
9-10. ....................................................... Алгоритмы поиска данных по образцу 40
Методические рекомендации ......................................................................... 40
Двоичный (бинарный) поиск элемента в массиве ...................................... 40
Интерполяционный поиск элемента в массиве ........................................... 41
Алгоритм Бойера-Мура ................................................................................. 42
3
Рекомендуемая литература ............................................................................. 44
Задания для развития и контроля владения компетенциями ...................... 45
11-12. ................................. Упорядочивание файловых последовательностей 46
Методические рекомендации ......................................................................... 46
Сортировка простым слиянием .................................................................... 46
Естественное слияние .................................................................................... 48
Рекомендуемая литература ............................................................................. 49
Задания для развития и контроля владения компетенциями ...................... 49
13-14. ................................................................... Базовые алгоритмы на графах 50
Методические рекомендации ......................................................................... 50
Алгоритмы обхода в глубину и по уровням ................................................ 50
Построение минимального остовного дерева ............................................. 51
Поиск кратчайшего пути ............................................................................... 53
Рекомендуемая литература ............................................................................. 54
Задания для развития и контроля владения компетенциями ...................... 55
15. Алгоритмы сжатия данных без потерь ..................................................... 56
Методические рекомендации ......................................................................... 56
Метод “Running”............................................................................................. 56
Словарные методы сжатия ............................................................................ 57
Алгоритм Хаффмана ...................................................................................... 59
Рекомендуемая литература ............................................................................. 61
Задания для развития и контроля владения компетенциями ...................... 61
16. Алгоритмы вывода графических примитивов ....................................... 63
Методические рекомендации ......................................................................... 63
Рисование отрезка .......................................................................................... 64
Простейший алгоритм закрашивания замкнутой области ......................... 69
Рекомендуемая литература ............................................................................. 70
Задания для развития и контроля владения компетенциями ...................... 71
Литература............................................................................................................ 72

4
Предисловие
Дисциплина «Технологии и методы программирования» имеет целью
обучить студентов принципам проектирования современного высокотехно-
логичного и безопасного программного обеспечения. Дисциплина «Техноло-
гии и методы программирования» имеет также цель по формированию науч-
ного мировоззрения и развитию системного мышления.
Дисциплина «Технология и методы программирования», в соответ-
ствии с федеральным государственным образовательным стандартом, явля-
ется обязательной учебной дисциплиной, входящей в базовую часть профес-
сионального цикла.
Для успешного овладения дисциплиной обучаемые должны владеть
знаниями и умениями полученными в ходе изучения дисциплин: «Логика»,
«Дискретная математика», «Информационные технологии» и «Языки про-
граммирования»
Дисциплина «Технологии и методы программирования» является базо-
вой для изучения таких учебных дисциплин, как «Программно-аппаратные
средства защиты информации», «Криптографические методы защиты ин-
формации», «Системы и сети передачи информации», «Безопасность инфор-
мационных систем» и др.
В результате успешного освоения дисциплины обучаемые приобретут
следующие компетенции:
 способностью применять программные средства системного, приклад-
ного и специального назначения (ПК-15);
 способностью использовать инструментальные средства и системы
программирования для решения профессиональных задач (ПК - 16);
 способностью к программной реализации алгоритмов решения типо-
вых задач обеспечения информационной безопасности (ПК-17).
Кроме того, обучающиеся должны:
знать:
 место и роль информационной безопасности в системе национальной
безопасности Российской Федерации;
 методы программирования и методы разработки эффективных алго-
ритмов решения прикладных задач;
 современные средства разработки и анализа программного обеспечения
на языках высокого уровня;

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

6
1-2 Технологичность программного обеспечения

Лабораторная работа – 4 часа

Цель занятия: исследование способов повышения качества программ-


ного обеспечения. Вырабатывает у обучаемого способность использовать
нормативные правовые документы в своей профессиональной деятельности
(ПК-3), способность организовать проведение и сопровождать аттестацию
объекта на соответствие требованиям государственных или корпоративных
нормативных документов (ПК - 6), способностью участвовать в разработке
подсистемы управления ин-формационной безопасностью (ПК - 12);.
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Что понимается под технологичностью программного продукта?
2. Что такое программный модуль?
3. Какие основные методы повышения технологичности ПО вам из-
вестны?
4. Что понимается под сцеплением модулей и какие виды сцепления
вам известны?
5. Что понимается под связностью модулей и какие виды связности
вам известны?

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

7
Чем выше независимость модулей, тем их легче понять, реализовывать,
модифицировать, а также находить в них ошибки и исправлять их.
Стиль программирования, под которым понимают стиль оформления
программ и их «структурность», также существенно влияет на читаемость
программного кода и количество ошибок программирования. Кризис 60-х го-
дов XX в. был вызван в том числе и стилем программирования, при котором
программа напоминала клубок спутанных ниток или блюдо спагетти, и от-
сутствием языковых конструкций поддержки «структурного» стиля.
Увеличение степени повторного использования кодов предполагает как
использование ранее разработанных библиотек подпрограмм или классов,
так и унификацию кодов текущей разработки. Причем для данного критерия
ситуация не так однозначна, как в предыдущих случаях: если степень по-
вторного использования кодов повышается искусственно (например, путем
разработки «суперуниверсальных» процедур), то технологичность проекта
может существенно снизиться.
Как следует из определения, высокая технологичность проекта особенно
важна, если разрабатывается программный продукт, рассчитанный на много-
летнее интенсивное использование, или необходимо обеспечить повышенные
требования к его качеству.

Модули и их свойства
При проектировании достаточно сложного программного обеспечения
после определения его общей структуры выполняют декомпозицию компо-
нентов в соответствии с выбранным подходом до получения элементов, ко-
торые, по мнению проектировщика, в дальнейшей декомпозиции не нужда-
ются.
Как уже упоминалось раньше, в настоящее время используют два спосо-
ба декомпозиции разрабатываемого программного обеспечения, связанные с
соответствующим подходом:
 процедурный (или структурный - по названию подхода);
 объектный.
Результатом процедурной декомпозиции является иерархия подпро-
грамм (процедур), в которой функции, связанные с принятием решения, реа-
лизуются подпрограммами верхних уровней, а непосредственно обработка -
подпрограммами нижних уровней. Это согласуется с принципом верти-
кального управления, который был сформулирован вместе с другими реко-
мендациями структурного подхода к программированию. Он также ограни-

8
чивает возможные варианты передачи управления, требуя, чтобы любая под-
программа возвращала управление той подпрограмме, которая ее вызвала.
Результатом объектной декомпозиции является совокупность объектов,
которые затем реализуют как переменные некоторых специально разрабаты-
ваемых типов (классов), представляющих собой совокупность полей данных
и методов, работающих с этими полями.
Таким образом, при любом способе декомпозиции получают набор свя-
занных с соответствующими данными подпрограмм, которые в процессе ре-
ализации организуют в модули.
Модули. Модулем называют автономно компилируемую программную
единицу. Термин «модуль» традиционно используется в двух смыслах. Пер-
воначально, когда размер программ был сравнительно невелик, и все подпро-
граммы компилировались отдельно, под модулем понималась подпрограмма,
т. е. последовательность связанных фрагментов программы, обращение к
которой выполняется по имени. Со временем, когда размер программ зна-
чительно вырос, и появилась возможность создавать библиотеки ресурсов:
констант, переменных, описаний типов, классов и подпрограмм, термин «мо-
дуль» стал использоваться и в смысле автономно компилируемый набор про-
граммных ресурсов.
Данные модуль может получать и/или возвращать через общие области
памяти или параметры.
Первоначально к модулям (еще понимаемым как подпрограммы) предъ-
являлись следующие требования:
 отдельная компиляция;
 одна точка входа;
 одна точка выхода;
 соответствие принципу вертикального управления;
 возможность вызова других модулей;
 небольшой размер (до 50-60 операторов языка);
 независимость от истории вызовов;
 выполнение одной функции.
Требования одной точки входа, одной точки выхода, независимости от
истории вызовов и соответствия принципу вертикального управления были
вызваны тем, что в то время из-за серьезных ограничений на объем оператив-
ной памяти программисты были вынуждены разрабатывать программы с
максимально возможной повторяемостью кодов. В результате подпрограм-
мы, имеющие несколько точек входа и выхода, были не только обычным яв-

9
лением, но и считались высоким классом программирования. Следствием же
было то, что программы было очень сложно не только модифицировать, но и
понять, а иногда и просто полностью отладить.
Со временем, когда основные требования структурного подхода стали
поддерживаться языками программирования, и под модулем стали понимать
отдельно компилируемую библиотеку ресурсов, требование независимости
модулей стало основным.
Практика показала, что чем выше степень независимости модулей, тем:
 легче разобраться в отдельном модуле и всей программе и соот-
ветственно тестировать, отлаживать и модифицировать ее;
 меньше вероятность появления новых ошибок при исправлении
старых или внесении изменений в программу, т. е. вероятность по-
явления «волнового» эффекта;
 проще организовать разработку программного обеспечения груп-
пой программистов и легче его сопровождать.
Таким образом, уменьшение зависимости модулей улучшает техноло-
гичность проекта. Степень независимости модулей (как подпрограмм, так и
библиотек) оценивают двумя критериями: сцеплением и связностью.

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

Связность модулей
Связность - мера прочности соединения функциональных и
информационных объектов внутри одного модуля. Если сцепление
характеризует качество отделения модулей, то связность характеризует
степень взаимосвязи элементов, реализуемых одним модулем. Размещение
сильно связанных элементов в одном модуле уменьшает межмодульные
10
связи и соответственно взаимовлияние модулей. В то же время помещение
сильно связанных элементов в разные модули не только усиливает межмо-
дульные связи, но и усложняет понимание их взаимодействия. Объединение
слабо связанных элементов также уменьшает технологичность модулей, так
как такими элементами сложнее мысленно манипулировать.
Различают следующие виды связности (в порядке убывания уровня):
 функциональную;
 последовательную;
 информационную (коммуникативную);
 процедурную;
 временную;
 логическую;
 случайную.

F1 F1
X

F F2 F2

а) б) в)

Функции Близкое Сходное


одной F1 время F1 F1
назначение
процедуры инициализации

F2 F2 F2

г) д) е)

Рисунок 2.1- Связность модулей: а - функциональная; б - последовательная;


в - информационная; г - процедурная; д - временная; е – логическая

11
Рекомендуемая литература
1. Технология программирования: учебник/ Г.С. Иванова. —
М.:КНОРУС, 2013. — 336 с.
2. Технологии объектно-ориентированного программирования:
учебник/ Хорев П.Б. — М.:Academia, 2013 — 448c.
Интернет-ресурсы
1. Материалы сайта корпорации Microsoft http://www.microsoft.ru
2. Материалы сайта компании Embarcadero
http://www.embarcadero.ru

Задания для развития и контроля владения компетенциями


Коллектив студентов (3-4 человека) получает от преподавателя задание
на проектирование программного модуля (модулей) и выполняет его с со-
блюдением требований к технологичности ПО.
Вариант задания: разработка программного модуля русификации кон-
сольного приложения
При работе в редакторе кода Delphi 7 исходный код программы набирает-
ся в ANSI кодировке, но при выводе на экран Windows использует таблицу
OEM.
OEM ANSI
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
3x sp ! " # $ % & ' 3x sp ! " # $ % & '
4x ( ) * + , - . / 0 1 4x ( ) * + , - . / 0 1
5x 2 3 4 5 6 7 8 9 : ; 5x 2 3 4 5 6 7 8 9 : ;
6x < = > ? @ A B C D E 6x < = > ? @ A B C D E
7x F G H I J K L M N O 7x F G H I J K L M N O
8x P Q R S T U V W X Y 8x P Q R S T U V W X Y
9x Z [ \ ] ^ _ ` a b c 9x Z [ \ ] ^ _ ` a b c
10x d e f g h i j k l m 10x d e f g h i j k l m
11x n o p q r s t u v w 11x n o p q r s t u v w
12x x y z { | } ~ • А Б 12x x y z { | } ~ • Ђ Ѓ
13x В Г Д Е Ж З И Й К Л 13x ‚ ѓ „ … † ‡ € ‰ Љ ‹
14x М Н О П Р С Т У Ф Х 14x Њ Ќ Ћ Џ ђ ‘ ’ “ ” •
15x Ц Ч Ш Щ Ъ Ы Ь Э Ю Я 15x – — ˜ ™ љ › њ ќ ћ џ
16x а б в г д е ж з и й 16x Ў ў Ј ¤ Ґ ¦ § Ё ©
17x к л м н о п ░ ▒ ▓ │ 17x Є « ¬ ® Ї ° ± І і

12
18x ┤ ╡ ╢ ╖ ╕ ╣ ║ ╗ ╝ ╜ 18x ґ µ ¶ · ё № є » ј Ѕ
19x ╛ ┐ └ ┴ ┬ ├ ─ ┼ ╞ ╟ 19x ѕ ї А Б В Г Д Е Ж З
20x ╚ ╔ ╩ ╦ ╠ ═ ╬ ╧ ╨ ╤ 20x И Й К Л М Н О П Р С
21x ╥ ╙ ╘ ╒ ╓ ╫ ╪ ┘ ┌ █ 21x Т У Ф Х Ц Ч Ш Щ Ъ Ы
22x ▄ ▌ ▐ ▀ р с т у ф х 22x Ь Э Ю Я а б в г д е
23x ц ч ш щ ъ ы ь э ю я 23x ж з и й к л м н о п
24x Ё ё Є Є Ї ї Ў ў ° ∙ 24x р с т у ф х ц ч ш щ
25x · √ № ¤ ■ 25x ъ ы ь э ю я

Обратите внимание на то, что:


Во-первых, коды кириллицы в этих таблицах полностью не совпадают.
Во-вторых, символы кириллицы в таблице OEM хранятся не последова-
тельно. После символа «п» (код символа 175) следует несколько десятков
символов псевдографики, и только затем символ «р» (код символа 224). Сим-
вол «Ё» вообще выбился из общей последовательности и оказался на пози-
ции 240.
Почему мы вспомнили эти две таблицы символов? А потому, что кон-
сольное приложение предназначено для работы с таблицей OEM, но ведь мы
создаём эту программу в среде Windows и более того, работаем в ней под
управлением Windows – а эта операционная система работает с таблицей
ANSI. Другими словами при вводе русского символа (ANSI код 192) наше
консольное приложение воспримет его как символ псевдографики «└» (OEM
код 192), так как код кириллического «А» в таблице OEM равен 128. Задача
ясна – нам необходимо, решить проблему преобразования кодов символов.
Вот так (в соответствии со всем вышеизложенным) выглядит функция
перевода ANSI символа в кодировку OEM.
function ANSI_TO_ASC(ch:char):char;
var bt:byte;
begin
bt:=Byte(ch);
case bt of
168 : result:=CHAR(240); {Ё}
184 : result:=CHAR(241); {ё}
192..239 : result:=CHAR(bt-64);{символы от “А” до “п”}
240..255 : result:=CHAR(bt-16) {символы от “р” до “я”}

13
else result:=ch;
end;
end;
Обратите внимание – преобразованию подвергаются только коды символов
русского алфавита, остальные символы проходят сквозь функцию транзитом
без каких либо изменений.
А так выглядит функция преобразования строки символов ANSI в строку
OEM.
function ANSI_TO_ASC_String(st : string):string;
var ch:char;
i:cardinal;
begin
Result:='';
for i:=1 to Length(st) do Result:=Result+ANSI_TO_ASC(st[i]);
end;
Для проверки работоспособности функций преобразования стоит повторить
следующий код.
const S1='АБВГДЕЁЖ...Я';
S2='абвгдеёж...я';
begin
WriteLn(ANSI_TO_ASC_String(S1));
WriteLn(ANSI_TO_ASC_String(S2));
ReadLn;
end.

14
3-4 Проектирование ПО при структурном подходе

Лабораторная работа – 4 часа

Цель занятия: исследование порядка разработки программного обеспе-


чения на основе объектного подхода. Вырабатывает у обучаемого способ-
ность использовать основные естественнонаучные законы, применять мате-
матический аппарат в профессиональной деятельности, выявлять сущность
проблем, возникающих в ходе профессиональной деятельности (ПК - 1),
способностью применять комплексный подход к обеспечению информаци-
онной безопасности в различных сферах деятельности (ПК - 30).
Организационная форма проведения занятия: круглый стол.
Вопросы, выносимые на обсуждение:
1. Для чего предназначена структурная схема ПО?
2. Что должно быть описано в функциональной схеме ПО?
3. Что такое “пошаговая детализация”?

Методические рекомендации
Структурная схема разрабатываемого программного обеспечения
Структурной называют схему, отражающую состав и взаимодействие
по управлению частей разрабатываемого программного обеспечения.
Структурные схемы п а к е т о в п р о г р а м м не информативны, по-
скольку организация программ в пакеты не предусматривает передачи управ-
ления между ними. Поэтому структурные схемы разрабатывают для каждой
программы пакета, а список программ пакета определяют, анализируя функ-
ции, указанные в техническом задании.
Самый простой вид программного обеспечения - программа, которая в
качестве структурных компонентов может включать только подпрограммы
(рис. 4.1).

15
Рисунок 3-4.1. – Пример структурной схемы ПО

Функциональная схема
Функциональная схема или схема данных (ГОСТ 19.701-90) - схема взаимо-
действия компонентов программного обеспечения с описанием информаци-
онных потоков, состава данных в потока: и указанием используемых файлов
и устройств. Для изображения функциональных схем используют специаль-
ные обозначения, установленные стандартом. Функциональные схемы более
информативны, чем структурные. Основные обозначения схем данных по
ГОСТ 19.701-90 приведены на рисунке 4.2.

16
Рисунок 3-4.2. – Обозначения для изображения функциональных схем (ГОСТ
19.701-90 )
На рисунке 4.2 для сравнения приведены функциональные схемы
программных комплексов и систем.

Рисунок 3-4.3. – Функциональная схема комплекса программ

17
Рисунок 3-4.4. – Функциональная схема системы программ
Все компоненты структурных и функциональных схем должны быть
описаны. При структурном подходе особенно тщательно необходимо прора-
батывать спецификации межпрограммных интерфейсов, так как от качества
их описания зависит количество самых дорогостоящих ошибок. К самым до-
рогим относятся ошибки, обнаруживаемые при комплексном тестировании, а
так как для их устранения могут потребоваться серьезные изменения уже от-
лаженных текстов.

Использование метода пошаговой детализации для проектирования


структуры программного обеспечения
Структурный подход к программированию в том виде, в котором он
был сформулирован в 70-х годах XX в., предлагал осуществлять
декомпозицию программ методом пошаговой детализации. Результатом
декомпозиции является структурная схема программы, которая представляет
собой многоуровневую иерархическую схему взаимодействия подпрограмм
по управлению. Минимально такая схема отображает два уровня иерархии,
т. е. показывает общую структуру программы. Однако тот же метод
позволяет получить структурные схемы с большим количеством уровней.
Метод пошаговой детализации реализует нисходящий подход и
базируется на основных конструкциях структурного программирования. Он
предполагает пошаговую разработку алгоритма. Каждый шаг при этом
включает разложение функции на подфункции. Так на первом этапе
описывают решение поставленной задачи, выделяя общие подзадачи, на
следующем аналогично описывают решение подзадач, формулируя при этом
подзадачи следующего уровня. Таким образом, на каждом шаге происходит
уточнение функций проектируемого программного обеспечения. Процесс

18
продолжают, пока не доходят до подзадач, алгоритмы решения которых
очевидны.
Декомпозируя программу методом пошаговой детализации, следует
придерживаться о с н о в н о г о п р а в и л а структурной декомпозиции,
следующего из принципа вертикального управления: в первую очередь дета-
лизировать управляющие процессы декомпозируемого компонента, оставляя
уточнение операций с данными напоследок. Это связано с тем, что приори-
тетная детализация управляющих процессов существенно упрощает
структуру компонентов всех уровней иерархии и позволяет не отделять
процесс принятия решения от его выполнения: так, определив условие
выбора некоторой альтернативы, сразу же вызывают модуль, ее
реализующий.
Детализация операций со структурами в последнюю очередь позволит
отложить уточнение их спецификаций и обеспечит возможность относитель-
но безболезненной модификации этих структур за счет сокращения количе-
ства модулей, зависящих от этих данных.
Кроме этого целесообразно придерживаться следующих рекомендации:
− не отделять операции инициализации и завершения от
соответствующей обработки, так как модули инициализации и
завершения имеют плохую связность (временную) и сильное
сцепление (по управлению);
− не проектировать слишком специализированных или слишком
универсальных модулей, так как проектирование излишне
специальных модулей увеличивает их количество, а
проектирование излишне универсальных модулей повышает их
сложность;
− избегать дублирования действий в различных модулях, так как при
их изменении исправления придется вносить во все фрагменты
программы, где они выполняются - в этом случае целесообразно
просто реализовать эти действия в отдельном модуле;
− группировать сообщения об ошибках в один модуль по типу
библиотеки ресурсов, тогда будет легче согласовать формулировки,
избежать дублирования сообщений, а также перевести сообщения
на другой язык.
При этом, описывая решение каждой задачи, желательно использовать не
более 1-2 структурных управляющих конструкций, таких как цикл-пока или

19
ветвление, что позволяет четче представить себе структуру организуемого
вычислительного процесса.

Рекомендуемая литература
1. Технология программирования: учебник/ Г.С. Иванова. —
М.:КНОРУС, 2014. — 336 с.
2. Технологии объектно-ориентированного программирования:
учебник/ Хорев П.Б. — М.:Academia, 2013 — 448c.
Интернет-ресурсы
1. Материалы сайта корпорации Microsoft http://www.microsoft.ru
2. Материалы сайта компании Embarcadero
http://www.embarcadero.ru

Задания для развития и контроля владения компетенциями


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

20
5-6 Фундаментальные структуры данных

Лабораторная работа – 4 часа

Цель занятия: исследование порядка представления в памяти простых


типов данных. Позволяет развить способность собрать и провести анализ ис-
ходных данных для проектирования подсистем и средств обеспечения ин-
формационной безопасности (ПК - 18).
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Что понимается под типом данных?
2. Как классифицируется типы данных?
3. Какие особенности работы со структурными типами данных вам из-
вестны?
4. Как представлены в памяти массивы и записи?

Методические рекомендации
Создателю языка Pascal профессору Цюрихской высшей технической
школы Николаусу Вирту принадлежит очень меткое определение:
ПРОГРАММА=СТРУКТУРЫ + АЛГОРТИМЫ
Первая лабораторная работа по дисциплине “Методы программирования”
посвящена знакомству с порядком определения и эффективного
использования в программах структур данных.
При решении какой-либо задачи как с помощью компьютера необходимо:
1. Выбрать некоторую абстракцию действительности, т. e.
определить множество данных, описывающих реальную
ситуацию.
2. Выбрать способ представления этой информации.
В качестве примера можно рассмотреть персональный файл студента.
Каждый студент представлен (абстрагирован) в этом файле множеством
данных, существенных либо для его характеристики, либо для процедур
расчета. Это множество может включать некоторую идентификацию
студента, например его имя и номер зачётной книжки. Но вряд ли оно будет
содержать такие несущественные данные, как цвет волос, вес и рост.

21
Для решения первой части задачи любой язык программирования обладает
заранее предопределёнными типами данных. Для решения второй части
задачи требуются знания и интуиция программиста.

Общее понятие типа данных


Отправной точкой процесса построения любой системы хранения и
обработки данных по праву считается тип данных. Вне зависимости от того,
какой язык программирования вы изучали, при построении новой
программы самым первым шагом становится рассмотрение типов данных
определяемых системой. Программистов Delphi, Си или поклонников
любого другого языка программирования не удивишь типами данных IN-
TEGER, REAL или CHAR. Указанные типы данных специализируются на
обслуживании целочисленных, вещественных или символьных значений. На
рисунке 6.1 представлена классификация наиболее распространенных типов
данных Delphi.
Типы данных определяют порядок хранения данных в памяти
компьютера. Типизация хранимых значений не просто указывает на
размерность в байтах, которую должна выделить система для размещения в
памяти того или иного значения. Преследуемая цель ещё более значима.
Типизация определяет, какие операции могут быть осуществлены с теми
или иными данными. Система программирования не позволит новичку
передать результаты деления в целочисленную переменную, ведь в этом
случае может быть утеряна дробная часть результата. Система станет
отчаянно сопротивляться, если мы попробуем просуммировать символьный
и вещественный тип данных. Пусть даже в символьной переменной
хранится числовое значение. В последнем случае перед проведением
математической операции необходимо повести преобразование данных.
Понятие “тип данных” интегрирует в себе три компоненты:
1. ограничение множества значений принадлежащих типу;
2. дефиниция набора операций применяемых к типу;
3. определение способа отображения (внешнего представления)
значений типа.
На сегодняшней лабораторной мы исследуем особенности представления в
памяти простых, строковых и некоторых структурных типов данных.

22
Целые

Символьные

Логические
Порядковые

Простые Перечислимые

Действительные
Поддиапазонны

Одномерные
Массивы
Строковые Многомерные

Фиксированные
Записи

Типы данных Вариантные


Множества

Структурные Файлы

Классы
Указательные
Указатели на
Процедурные классы

Вариантные

Рисунок 5-6.1. – Классификация стандартных типов данных Delphi

Простой тип
При работе с простыми типами данных предполагается, что:
1. все действия с данными простого типа являются точными;
2. действия выполняются по обычным правилам арифметики;
3. вычисление прерывается, если результат оказывается за
границами допустимого подмножества.
В таблицах 6.1. – 6.4 вы найдете описание целого, символьного, логического
и действительного типов данных.
Таблица 5-6.1. Целые числа
Тип Диапазон значений Размер в байтах
Int64 –263 .. 263–1 8
Integer (Longint) –2147483648 .. 2147483647 4
Smallint –32768 .. 32767 2
Shortint –128 .. 127 1
Byte 0 .. 255 1
23
Word 0 .. 65535 2
Cardinal 0 .. 4294967295 4
(LongWord)

Таблица 5-6.2. Символьный тип данных


Тип Кодировка Размер в байтах
Char (AnsiChar) ANSI 1
WideChar UNICODE 2

Таблица 5-6.3. Логический тип данных


Тип Диапазон значений Размер в бай-
тах
Boolean 0 – false; 1 – true; 1
ByteBool от 0 до 255, где 0 – false, 1..255 – true 1
WordBool от 0 до 65535, где 0 – false, 1..65535 – true 2
LongBool от 0 до 4294967295, где 0 – false, 1..4294967295 4
– true

Действительные (вещественные) типы данных предназначены для работы со


значениями, содержащими не только целую, но и дробную часть.
Таблица 5-6.4. Действительные типы данных
Тип Диапазон значений Количество Размер в
знаков байтах
Real48 2.9 x 10–39 .. 1.7 x 1038 11–12 6
Single .5 x 10–45 .. 3.4 x 1038 7–8 4
Double (Real) 5.0 x 10–324 .. 1.7 x 10308 15–16 8
Extended 3.6 x 10–4951 .. 1.1 x 104932 19–20 10
Comp –263+1 .. 263 –1 19–20 8
Currency -922337203685477.5808.. 19–20 8
922337203685477.5807

24
Перечислимые типы данных
Перечислимые типы относятся к типу данных, определяемых
программистом. Перечислимый тип данных задаётся списком имён.

type TypeName = (Value1, Value2,..., ValueN);

Числа, логические и символьные константы не могут быть элементом


перечислимого типа. В качестве примера представим перечислимый тип,
соответствующий дням недели:

type TypeWeekDay =(Mon, Tu, We, Th, Fr, Sa, Su);


//. . .
var WDay1, WDay2 : TypeWeekDay;
begin
WDay1 : =Mon;
WDay2 : =Tu;
end;

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


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

if WDay1<WDay2 then …

Поддиапазонны
Переменная, входящая в поддиапазон, может принимать значения только в
пределах границ диапазона.

type TSubIntegerRange = 10 .. 100;


type TSubCharRange = ’A’ .. ’Z’;
...
var IntValue : TSubIntegerRange;
CharValue : TSubCharRange;
...
MyValue :=50;
CharValue := 'X';

Исходя из примера, переменная IntValue сможет хранить целочисленные


значения от 10 до 100, а переменная CharValue – прописные латинские сим-
волы от “A” до “Z”.

25
Строковый тип
Строковый тип данных предназначен для хранения последовательности
букв, цифр и других символов. Обычная строка представляет собой ничто
иное, как массив символьных значений и плюс некоторая служебная
информация. В Delphi реализовано четыре основных строковых типа (см.
таблицу 6.5).
Таблица 5-6.5. Строковый тип данных
Тип Максимальная длина Размер в памяти
ShortString 255 символов 2 .. 256 байт
String определяется директивой компилятора $H. Если она включена,
то соответствует AnsiString, иначе ShortString
AnsiString около 231символов 4 байта .. 2 Гбайта
WideString около 230символов 4 байта .. 2 Гбайта

Структурные типы
Основное назначение структурных типов – совместное хранение множества
однотипных или разнотипных значений.

Массивы
Массив это регулярная структура: все его компоненты - одного типа,
называемого базовым типом. Массив также это структура с так называемым
случайным доступом, все его компоненты могут выбираться произвольно и
являются одинаково доступными.
Плюсов у массива всего два, но зато больших:
1. доступ за константное время к любому элементу;
2. память тратится только на данные.
Минус – один, но тоже большой: статичность, неизменность структуры.
Массив, как и переменную необходимо объявить. Для этого необходимо
указать размерность массива и тип хранимых данных:
var <Имя_массива>: array [<нижняя граница> .. <верхняя граница>] of
<тип_элементов>;
Если вы полагаете, что в программе будет применяться несколько
однотипных массивов, то предварительно стоит определить тип массива, и
затем создавать массивы на базе объявленного типа.

26
type TMyArray = Array [0..9] of integer; // массив из 10 элементов
Var Array1, Array2 : TMyArray;

Для обращения к элементам массива с целью чтения или записи достаточно


указать индекс элемента в массиве:

NewArray[0]:=199; // 0 элементу массива присваивается значение 199


I:=NewArray[9]; // в переменную I записано содержимое 9-го элемента
массива

Иногда полезно задавать массив в виде константы. В нижеприведённом


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

const
DaysInMonth: array [1..12] of byte = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30,
31);

Вполне реально объявлять "квадратные", "кубические" массивы и массивы


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

var MyArray : Array[0..9,0..9] of cardinal;

или

var MyArray : Array[0..9] of Array[0..9] of cardinal;

Но теперь, для того, чтобы обратиться к интересующей нас ячейке


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

MyArray[3,6]:=56;

или

MyArray[3][6]:=56;

У рассмотренного выше способа хранения данных есть один существенный


недостаток – объявив размерность массива (сделав его статическим), мы не
сможем выйти за его границы. А что делать, если заранее даже приблизи-
тельно не известно, сколько элементов может оказаться в массиве? В таких
случаях используют динамические массивы. Характерным отличием дина-
мического массива от статического заключается в том, что границы такого
массива могут изменяться во время работы приложения.

27
Естественно, что объявление динамического массива выглядит несколько
иначе:

var MyArray: array of INTEGER;

Как видите, при объявлении массива мы не определяем его размерность. Но,


перед заполнением массива нам, всё-таки, это придётся сделать с помощью
метода SetLength():

SetLength(MyArray, 10); //распределяем память для 10-ти элементов

Отсчёт элементов динамического массива всегда начинаются с нуля. Если


вы работаете с многомерным динамическим массивом следующего вида:

var MyArray : Array of Array of Char;

то все размерности массива можно задавать одновременно:

SetLength(MyArray, 10, 5); //распределили память для 2-х мерного массива

или последовательно для каждого индекса. Такие массивы (с переменной


длиной по разным индексам) называют динамическими разреженными
массивами.

SetLength(MyArray,3); //массив состоит из 3-х строк


SetLength(MyArray[0],3); //в нулевой строке 3 элемента
SetLength(MyArray[1],2); //в первой – 2 элемента
SetLength(MyArray[2],10); //во второй – 10 элементов

Записи
Рассмотрим небольшую задачу. Необходимо организовать учёт сотрудников
фирмы. Учету подлежат: фамилия работника, его заработная плата и стаж
работы на предприятии в годах. На первый взгляд решение лежит на ладони
– берём три переменных типа String, Currency и Byte соответственно с их
помощью обрабатываем данные. Но эта задача решается элегантнее с
помощью механизма записей! Объявляем тип TPeople:

Type TPeople = Record


Surname : String;
Money : Currency;
Experience : byte;
end;

28
Запись TPeople определяет единый тип данных, содержащий три
разнотипных элемента, называемых полями записи. Доступ к полям записи
осуществляют по их имени. Вот пример заполнения такой записи:

var People : TPeople; //объявление переменной на основе типа данных


TPeople
begin
People.Surname := 'Петров';
People.Money := 1500.55;
People.Experience := 10;
end;

Современный синтаксис позволяет создавать записи с различными


вариантами полей. Будем назвать такую запись записью с вариантным
полем. Синтаксис объявления выглядит следующим образом:
type <имя_типа_записи> = record
<поле_1>: <тип_данных_1>;
<поле_2>: <тип_данных_2>;
...
case <поле_N>: <порядковоый_тип_данных> of
значение_1: (вариант 1);
...
значение_M: (вариант 2);
end;
Отличительная особенность записи с вариантным полем – наличие внутри
её оператора-селектора Case.

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

type TIntSet = set of 1..10;

В качестве элементов множества могут использоваться любые порядковые


типы данных:

type TCharSet = set of 'A'.. 'Z';

кроме того, вы имеете право определять свои собственные элементы


множества:

29
type TWeekDays = set of (Mo, Tu, We, Th, Fr, St, Su);

Чем же отличаются множества от изученных ранее поддиапазонов?


Представьте себе, что вы работаете в театре, правда, пока не главным
режиссёром, а лишь осветителем. Так как театр весьма небольшой, то в
распоряжении осветителя лишь три прожектора:

type TLampsSet = set of (Lamp1, Lamp2, Lamp3);

При освещении сцены осветитель в состоянии зажечь любой из прожекто-


ров, или два, или все, короче говоря, выбрать любую понравившуюся ком-
бинацию. Если ассоциировать прожектора с ячейками памяти компьютера,
то это всего на всего три бита. Единичка в ячейке свидетельствует о вклю-
чении, нолик о выключении соответствующего прожектора. Если множе-
ство содержит всего три элемента, то общее количество возможных комби-
наций составляет 23=8. Зарезервированное слово Set способно определять
множество размерностью до 256 элементов. Возведите 2 в степень 256. и
получите 1,1579208923731619542357098500869e+77 вариантов. На практике
такого количества вариаций никогда не понадобиться. В частности разра-
ботчики Delphi рекомендуют использовать множество с количеством эле-
ментов не более 16.

Представление структур в памяти


Проблема представления данных есть проблема отображения абстрактной
структуры в память вычислительной машины. В первом приближении эта
память представляет собой массив отдельных ячеек памяти, называемых
словами (word). Индексы этих слов называются адресами (address):
Представление массива — это отображение (абстрактного) массива
компонент типа T в память, которая представляет собой массив компонент
типа word.

Массив следует отображать таким способом, чтобы можно было


максимально просто и потому эффективно вычислять адреса его
компонент.

Адрес, или индекс памяти, i-ой компоненты массива вычисляется с помо-


щью линейной функции отображения
i  i0  i  S , (6.1).

Где: i0 – адрес первой компоненты; S – число слов, которые занимает


компонента.

30
Память

i0

МАССИВ

Рисунок 5-6.2. – Представление массива в памяти


Так как по определению WORD есть минимальная доступная единица
памяти, то, по-видимому, желательно, чтобы S было целым числом. Если S
не целое число слов памяти (а так бывает довольно часто), то S обычно
округляется до ближайшего большего целого числа [s]. В этом случае
каждая компонента массива занимает [S] слов, причем часть слова
величиной [S] - S остается неиспользованной

Округление числа занимаемых слов до ближайшего целого называется


выравниванием.

Отношение размера памяти, которая отводится для описания струк-


туры данных, к размеру действительно занятой памяти называется коэффи-
циентом использования памяти:
s s
u  , (6.2).
s' [ s]

С одной стороны, разработчик стремится получить коэффициент


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

31
3. Обращение к частям слова может удлинить программу
(оттранслированную) и этим свести на нет выигрыш, достигнутый
отказом от выравнивания.
Упаковкой называется приём помещения в каждое слово более одной
компоненты массива

Записи отображаются в память простым объединением отображений их


компонент. Адрес компоненты ri относительно начального адреса записи
называется смещением ki.
ki  S1  S2  ...  Si 1 , (6.3)

где Si – размер компоненты.


Если в одно слово можно укладывать несколько компонент записи, то
упаковка позволит экономить память (см. рис. 6.3).

S1

S2 S3

S4 Выравнивание

S5

S6

Рисунок 5-6.3. – Представление в памяти упакованной записи


Желательность упаковки будет обозначаться словом packed перед словом ar-
ray (или record).

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. –
СПб.: Невский Диалект, 2013. – 352 с.: ил.
2. Дональд Э. Кнут. Искусство программирования. Том 1. Основные
алгоритмы 3-е издание — СПб.:Вильямс, 2015. — 720 с.
3. Кормен. Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ.—
М.; МЦНМО, 2014, 960 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.
32
Задания для развития и контроля владения компетенциями
1. Разработайте структуру данных позволяющую составлять прайс-
лист магазина. В прайс-лист входят следующие позиции: название
товара, цена за единицу, единица измерения, количество.
2. Подготовьте структуру данных позволяющую создавать
расписание телепередач на неделю. В расписание входят
следующие позиции: день недели, номер канала, время начала
передачи, название передачи, жанр передачи.
3. Подготовьте структуру, предназначенную для описания
информации в зачётной книжке студента. Необходимо
предусмотреть следующие поля данных: дисциплина, количество
часов, вид отчётности (экзамен, зачёт, курсовая работа), оценка.
4. Предложите структуру для хранения информации о произвольной
музыкальной мелодии. Помимо тона звуков, ваша структура
должна уметь описывать длительность звучания каждой ноты.
Совет: При определении записей (record) и массивов (array) исследуйте
какой объём памяти выделяется для ваших структур при включённом и
отключённом режимах упаковки (packed). Для этого вам понадобится
помощь функции:
function SizeOf(X): Integer; {возвращает число задействованных байт}
Сделайте выводы об особенностях определения структур с учётом миними-
зации расхода памяти.
Примечание:
Результаты работы оформляются в письменном виде. В отчёте следует схе-
матично изобразить представление в памяти данных в упакованном и не-
упакованном виде.

33
7-8 Простейшие методы сортировки массивов

Лабораторная работа – 4 часа

Цель занятия: исследование простейших методов сортировки одномер-


ных массивов. Позволяет развить способность собрать и провести анализ ис-
ходных данных для проектирования подсистем и средств обеспечения ин-
формационной безопасности (ПК - 18) и способность использовать основные
естественнонаучные законы, применять математический аппарат в професси-
ональной деятельности, выявлять сущность проблем, возникающих в ходе
профессиональной деятельности (ПК - 1).
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Что такое указатель?
2. Какой объём памяти отводится для хранения указателя?
3. Для чего необходима структура данных “список”?
4. Что понимается под связным списком?
5. Какие разновидности связных списков вам известны?

Методические рекомендации
Под сортировкой понимается процесс перестановки объектов какого-то
множества в определённом порядке.

Цель сортировки – облегчить последующий поиск элементов в


отсортированном множестве.

Поиск прототипов современных методов сортировки начался в XIX веке.


Герман Холлерит в 1888 году изобрёл электрический табулятор, работа ко-
торого базировалась на принципах поразрядной сортировки.
Сортировка является примером огромного разнообразия алгоритмов,
выполняющих одну и ту же задачу, многие из которых являются
оптимальными, имея какое-то преимущество над остальными.
Выбор алгоритма сортировки очень сильно зависит от структуры данных.
Текущая лабораторная работа посвящена сортировкам массивов.

Оценка алгоритмов сортировки


Алгоритмы сортировки обычно оцениваются по 3 параметрам:
34
1. Время сортировки – основной параметр, характеризующий
быстродействие алгоритма.
2. Память – ряд алгоритмов требует выделения дополнительной
памяти под временное хранение данных.
3. Устойчивость – устойчивая сортировка не меняет взаимного
расположения равных элементов. Такое свойство может быть
очень полезным, если они состоят из нескольких полей, а
сортировка происходит по одному из них.
Если критерий экономии памяти принят за ограничение, то удобная мера
эффективности получается при подсчёте числа C необходимых сравнений
ключей и M пересылок элементов.
Числа M и C определяются функциями от числа N сортируемых элементов.
Рассматриваемые сегодня алгоритмы предусматривают N2 сравнений. Это
далеко не лучший показатель, поэтому все эти алгоритмы относятся к
классу простых.

Сортировка простым обменом


44 06 06 06 06 06 06 06
(пузырьковый метод)
55 44 12 12 12 12 12 12
Алгоритм сортировки простым
обменом основан на 12 55 44 18 18 18 18 18

следующем принципе: 42 12 55 55 42 42 42 42

осуществляется просмотр всех


94 42 42 42 55 44 44 44
элементов массива с целью
выявления элемента с 18 94 94 94 94 94 55 55

наименьшим весом, найденный 06 18 18 44 44 55 94 67

элемент переносится в первую


67 67 67 67 67 67 67 94
позицию массива, а основные
Рисунок 7-8.1.– Сортировка простым обменом
элементы смещаются. На
следующей итерации алгоритма процедура повторяется, но уже без учёта
первого элемента, и т.п. Очень часто этот метод называют “пузырьковым”,
когда элемент с наименьшим весом всплывает на поверхность.
Работа алгоритма становится нагляднее, если развернуть массив по
вертикали (см. рис. 8.1).

Шейкер-сортировка
Сортировка пузырьковым методом обладает примечательным недостатком –
один неправильно расположенный “лёгкий пузырёк” расположенный в
“тяжёлом конце” всплывёт на место за один проход.
35
Например: 12,8,42,44,55,67,94,06
44 06 06 06 06 06 06 06

Неправильно расположенный 55 44 44 12 12 12 12 12
элемент в “лёгком” конце массива
12 55 55 55 55 18 18 18
будет опускаться за несколько
42 12 12 44 44 44 44 42
проходов.
94 42 42 42 42 42 42 44

Например: 94,06,12,8,42,44,55,67 18 94 67 67 18 55 55 55

Эта неестественная асимметрия 06 18 18 18 67 67 67 67

подсказывает направление улучше- 67 67 94 94 94 94 94 94

ния алгоритма – менять направление Рисунок 7-8.2.– Шейкер-сортировка


следующих друг за другом прохо-
дов. Работа такого алгоритма продемонстрирована рисунком 8.2.
В отличие от сортировки пузырьком (которая не находит места в серьёзных
программах), шейкер-сортировка с успехом применяется в тех случаях,
когда заранее известно, что все элементы почти упорядочены.

Сортировка простым выбором


Метод основан на следующем правиле:
1. Находится элемент с наименьшим ключом;
2. Он меняется местами с первым элементом a1.
Эти операции повторяются с n-1 элементами, затем с n-2, и т.д. пока не
останется только один элемент – наибольший (см. рис. 4.3).
44 55 12 42 94 18 06 67

06 55 12 42 94 18 44 67

06 12 55 42 94 18 44 67

06 12 18 42 94 55 44 67

06 12 18 42 94 55 44 67

06 12 18 42 44 55 94 67

06 12 18 42 44 55 94 67

06 12 18 42 44 55 67 94

Рисунок 7-8.3. – Сортировка простым выбором


В самом общем виде алгоритм может быть сформулирован следующим
образом:

36
FOR i:=0 TO n-1 DO
BEGIN
{ Присвоить k индекс наименьшего из a[i] … a[n];
Поменять местами a[i] и a[k]}
END;
44 55 12 42 94 18 06 67
Сортировка простыми
44 55 12 42 94 18 06 67
вставками
Элементы исходного массива 12 44 55 42 94 18 06 67

условно разделяются на готовую


12 42 44 55 94 18 06 67
последовательность A[0], …,
A[i] и входную 12 42 44 55 94 18 06 67
последовательность A[i+1], …,
12 18 42 44 55 94 06 67
A[n]. На каждом шаге, начиная с
i=1 и увеличивая i на единицу 06 12 18 42 44 55 94 67
берут i –й элемент входной
06 12 18 42 44 55 67 94
последовательности и передают
в готовую последовательность, Рисунок 7-8.4. – Сортировка простыми вставками

вставляя его на подходящее место. Порядок работы алгоритма отражён на


рисунке 4.4.
Ваш алгоритм будет выглядеть примерно так:
Var a : array [0..99] of …;
begin
For i:=1 to n-1 do
Begin
x:=a[i];
{вставить x в подходящее место}
End;

Обратите внимание, что сортировки простыми вставками и простым выбо-


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

37
Сортировка бинарными вставками
Алгоритм сортировки простыми вставками можно улучшить, пользуясь тем,
что готовая последовательность A[0],…,A[i] (в которую нужно включить
новый элемент) уже упорядочена. Поэтому место включения можно найти
значительно быстрее.
Будем разбирать алгоритм, рассматривая его действия на i-м шаге. Как
говорилось выше, последовательность к этому моменту разделена на две
части: готовую A[0]...A[i] и неупорядоченную A[i+1]...A[n]. Выбираем
любой элемент из неупорядоченной последовательности и сравниваем его с
элементом, находящимся в центре уже отсортированной
последовательности.
Часть A[0]..A[4] уже упорядочена.
Центр упорядоченной
последовательности

12 42 44 55 94 18 06 67

44 > 18,
значит 18 будет находиться левее 44
Рисунок 7-8.5.– Шаг сортировки бинарными включениями
Произведя сравнение, мы получаем важную информацию о том, в какой по-
ловине уже отсортированной последовательности должен оказаться очеред-
ной элемент. В нашем случае (см. рис. 8.5) элемент 18 меньше 44, поэтому
он должен попасть левее элемента массива со значением 44. Далее операция
повторяется с выбранной частью отсортированной последовательности до
тех пор, пока наш элемент не попадёт в установленное место.

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. –
СПб.: Невский Диалект, 2014. – 352 с.: ил.
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в
Delphi. Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.:
Питер, 2016 – 557 с.
3. Дональд Э. Кнут. Искусство программирования. Том 1. Основные
алгоритмы 3-е издание — СПб.:Вильямс, 2014. — 720 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

38
Задания для развития и контроля владения компетенциями
1. Подготовьте одномерный массив целых чисел произвольной размерности
и заполните его случайными значениями. Разработайте пять функций
сортирующих произвольный массив целых чисел изучаемыми на
лабораторной работе простыми методами сортировки.
2. Разработайте процедуру сортировки 2-хмерного массива с применением
любого из изученных вами алгоритмов сортировок. Подумайте, можно
ли её сделать универсальной – способной упорядочивать произвольные
N-мерные массивы.
3. Объявите одномерный массив, типизированный типом данных TPoint.
type TPoint = packed record
X: Longint;
Y: Longint;
end;
Заполните массив случайными числами и разработайте процедуру
сортировки упорядочивающую элементы массива по полям X и Y
(сначала по полю X, при условии равенства X у элементов массива
сортировка осуществляется по полю Y).

Совет. Разработайте универсальную процедуру вывода содержимого


массива на экран и используйте её для оценки правильности работы
ваших программ.

39
9-10 Алгоритмы поиска данных по образцу

Лабораторная работа – 4 часа

Цель занятия: исследование методов поиска данных в упорядоченных и


неупорядоченных последовательностях. Позволяет развить способность со-
брать и провести анализ исходных данных для проектирования подсистем и
средств обеспечения информационной безопасности (ПК - 18) и способность
использовать основные естественнонаучные законы, применять математиче-
ский аппарат в профессиональной деятельности, выявлять сущность про-
блем, возникающих в ходе профессиональной деятельности (ПК - 1).
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Где на практике следует применять алгоритмы поиска данных?
2. Какой основной недостаток алгоритма прямого поиска?
3. Как надо модифицировать алгоритм Бойера-Мура для поиска тек-
ста в кодировке Unicode?

Методические рекомендации
Поиск подстроки в длинном куске текста – важный элемент текстовых
редакторов. Однако ту же самую технику можно использовать для поиска
битовых или байтовых строк в двоичном файле. Так, например,
осуществляется поиск вирусов в памяти компьютера. В данной
лабораторной работе мы исследуем три метода поиска данных. Два из них
работают на упорядоченной последовательности символов, третий
позволяет найти данные на неупорядоченной последовательности.

Двоичный (бинарный) поиск элемента в массиве


Если у нас есть массив, содержащий упорядоченную последовательность
данных, то очень эффективен двоичный поиск.
Допустим, что переменные L и R содержат, соответственно, левую и правую
границы отрезка массива, где находится нужный нам элемент. Мы начинаем
всегда с исследования среднего элемента отрезка. Если искомое значение
меньше среднего элемента, мы переходим к поиску в верхней половине
отрезка, где все элементы меньше только что проверенного. Другими
словами, значением R становится (M – 1) и на следующей итерации мы
40
работаем с половиной массива. Таким образом, в результате каждой
проверки мы вдвое сужаем область поиска. Так, в нашем примере, после
первой итерации область поиска – всего лишь три элемента, после второй
остается всего лишь один элемент. Таким образом, если длина массива
равна 6, нам достаточно трех итераций, чтобы найти нужное число.
Двоичный поиск - очень мощный метод. Если, например, длина массива
равна 1023, после первого сравнения область сужается до 511 элементов, а
после второй - до 255. Легко посчитать, что для поиска в массиве из 1023
элементов достаточно 10 сравнений.

Интерполяционный поиск элемента в массиве


Представьте себе, что вы ищете слово в словаре. Маловероятно, что вы
сначала загляните в середину словаря, затем отступите от начала на 1/4 или
3/4 и т.д, как в бинарном поиске.
Если нужное слово начинается с буквы 'А', вы наверное начнете поиск где-
то в начале словаря. Когда найдена отправная точка для поиска, ваши
дальнейшие действия мало похожи на рассмотренный выше метод
двоичного поиска.
Если вы заметите, что искомое слово должно находиться гораздо дальше
открытой страницы, вы пропустите порядочное их количество, прежде чем
сделать новую попытку. Это в корне отличается от алгоритма двоичного
поиска, не делающего разницы между “много больше” и “чуть больше”.
Мы приходим к алгоритму, называемому интерполяционным поиском: Если
известно, что К лежит между Kl и Ku, то следующую пробу делаем на
расстоянии (u  1)( K  K1 ) / Ku  K1 от l, предполагая, что ключи являются
числами, возрастающими приблизительно в арифметической прогрессии.
На практике, интерполяционный поиск часто быстрее бинарного, так как с
вычислительной стороны их отличают лишь применяемых арифметические
операции: интерполирование - в интерполирующем поиске и деление на два
- в двоичном, а скорость их вычисления отличается незначительно, с другой
стороны интерполирующий поиск использует такое принципиальное
свойство данных, как однородность распределения значений. Бинарный
поиск учитывает лишь знак разности между ключом и текущим значением, а
интерполирующий ещё учитывает и модуль этой разности и по данному
значению производит предсказание позиции следующего элемента для
проверки. В среднем, интерполирующий поиск производит log(log(N))
операций, где N есть число элементов, среди которых производится поиск.

41
Число необходимых операций зависит от равномерности распределения
значений среди элементов. В плохом случае (например, когда значения
элементов экспоненциально возрастают) интерполяционный поиск может
потребовать до O(N) операций.

Алгоритм Бойера-Мура
Простейшую процедуру поиска подстроки в неупорядоченной текстовой
строке можно интерпретировать графически как скольжение шаблона с
искомой подстрокой по тексту. На рисунке 10.1 проиллюстрированы три
последовательных положения шаблона с образцом искомого текста “AAB”
относительно текста “ACAABC”.

A C A A B C A C A A B C A C A A B C

+ ! ! + + +
S=1 S=2
S=0 A A B A A B A A B

Рисунок 9-10.1. – Простейший алгоритм поиска подстроки для образца


“AAB” и текста “ACAABC”
Основной операцией простейшего алгоритма выступает сравнение симво-
лов, поэтому именно число сравнений и следует подсчитывать. В наихуд-
шем случае при каждом проходе совпадают все символы за исключением
последнего. Если длина подстроки равна S, а длина текста равна Т, то, в
наихудшем случае число сравнений будет равно S(T- S +1). Проблема стан-
дартного алгоритма заключается в том, что он затрачивает много усилий
впустую.
Алгоритм Бойера-Мура, разработанный двумя учеными – Бойером (Robert
S. Boyer) и Муром (J. Strother Moore), считается наиболее быстрым среди
алгоритмов общего назначения, предназначенных для поиска подстроки в
строке неупорядоченных символов.
Простейший вариант алгоритма Бойера-Мура состоит из следующих шагов:
1. Строим таблицу смещений для искомого образца.
2. Совмещаем начало строки и образца и начинаем проверку с последнего
символа образца.
3. Если последний символ образца и соответствующий ему при
наложении символ строки не совпадают, образец сдвигается

42
относительно строки на величину, полученную из таблицы смещений,
и снова проводится сравнение, начиная с последнего символа образца.
4. Если же символы совпадают, производится сравнение предпоследнего
символа образца и т. д. Если все символы образца совпали с
наложенными символами строки, значит мы нашли подстроку и поиск
окончен.
5. Если же какой-то (не последний) символ образца не совпадает с
соответствующим символом строки, мы сдвигаем образец на один
символ вправо и снова начинаем проверку с последнего символа.
Правила построения таблицы смещений. Величина сдвига в случае
несовпадения последнего символа вычисляется исходя из следующих
соображений:
1. Сдвиг образца должен быть минимальным, таким, чтобы не пропустить
вхождение образца в строке.
2. Если данный символ строки встречается в образце, мы смещаем
образец таким образом, чтобы символ строки совпал с самым правым
вхождением этого символа в образце.
3. Если же образец вообще не содержит этого символа, мы сдвигаем
образец на величину, равную его длине, так что первый символ образца
накладывается на следующий за проверявшимся символ строки.
Пример предложен на рисунке 10.2. Пусть у нас есть набор символов из
пяти символов: a, b, c, d, e и мы хотим найти вхождение образца “abbad” в
строке “abeccacbadbabbad”.

a b c d e Таблица смещений для


1 2 5 0 5 образца “ abbad”

5
1
a b b a d 2 0 a b b a d

a b b a d 5 a b b a d

a b b a d
Рисунок 9-10.2. – Таблица смещений для образца “abbad”
Рассмотрим алгоритм в действии. Начало поиска представлено на рисунке
10.3. Последний символ образца не совпадает с наложенным символом
строки.
43
a b c d e a b e c c a c b a d b a b b a
1 2 5 0 5 !
a b b a d
Рисунок 9-10.3. – Начало поиска подстроки в строке
Последний символ образца “d”, а в исходной строке встретился символ “c”.
Согласно таблице смещений нам следует переместить образец на пять
позиций вправо (см. рис. 10.4).

ab e c c a c b a d b a b b a d
! + + +
a b b a d
5

Рисунок 9-10.4 – Проверка совпадения символов после сдвига на 5 позиций


Три символа образца совпали, а четвертый – нет. Сдвигаем образец вправо
на 1 позицию:

a b c d e ab e c c a c b a d b a b b a d
1 2 5 0 5 !
a b b a d
1

Рисунок 9-10.5 – Проверка соответствия после сдвига на 1 позицию


Таким образом, будет продолжена проверка всей строки до последнего
символа или до полного совпадения образца с символами в строке.

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. –
СПб.: Невский Диалект, 2015. – 352 с.: ил.
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в
Delphi. Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.:
Питер, 2016 – 557 с.
3. Дональд Э. Кнут. Искусство программирования. Том 1. Основные
алгоритмы 3-е издание — СПб.:Вильямс, 2014. — 720 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

44
Задания для развития и контроля владения компетенциями
На основе рассмотренных на текущей лабораторной работе алгоритмов
разработайте программы реализующие двоичный поиск, интерполяционный
поиск и алгоритм Бойера-Мура. Первые две из перечисленных программ
должны производить поиск в упорядоченных последовательностях, а
алгоритм Бойера-Мура позволит искать подстроку в произвольных текстах.

При выполнении задания целесообразно воспользоваться услугами


многострочного редактора – компонента TMemo информацию о
котором вы найдёте в приложениях к этому материалу.

45
11-12 Упорядочивание файловых
последовательностей

Лабораторная работа – 4 часа

Цель занятия: исследование принципов сортировки последовательно-


стей. Позволяет развить способность собрать и провести анализ исходных
данных для проектирования подсистем и средств обеспечения информацион-
ной безопасности (ПК - 18), способность использовать основные естествен-
нонаучные законы, применять математический аппарат в профессиональной
деятельности, выявлять сущность проблем, возникающих в ходе профессио-
нальной деятельности (ПК - 1) и способность использовать инструменталь-
ные средства и системы программирования для решения профессиональных
задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Что понимается под последовательным хранением данных?
2. Какие следствия последовательного доступа вам известны?
3. Как организовать доступ к файлу для чтения (для записи)?
4. Как предотвратить операцию чтения за пределами файла?
5. Какие основные и дополнительные операции над последователь-
ным файлом вам известны?

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

Слияние обозначает объединение двух (или более) упорядоченных


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

Сортировка простым слиянием


Идея метода сортировки простым слиянием заключается в следующем:
1. Последовательность A разбивается на две половины B и C;

46
2. Последовательности B и C сливаются при помощи объединения
отдельных элементов в упорядоченные пары;
3. Полученной последовательности присваивается имя A и шаги 1 и 2
повторяются, но на этот раз упорядоченные пары сливаются в
упорядоченные четвёрки;
4. Предыдущие шаги повторяются: четвёрки сливаются в восьмёрки и
весь процесс продолжается пока не будет упорядочена вся
последовательность (ведь длины слагаемых последовательностей
всегда удваиваются).
Изложенная идея представлена на рисунке 12.1.
1) Разделение исходного файла A
44 55 12 42

44 55 12 42 94 18 06 67

94 18 06 67

2) Файл B

44 55 12 42 Файл A составляется из упорядоченных пар

44 94 18 55 06 12 42 67

94 18 06 67

Файл C
Файл B

3) Файл A вновь разделяется пополам


44 94 18 55

44 94 18 55 06 12 42 67 Файл C

06 12 42 67

Рисунок 11-12.1. – Процесс разделения и слияния файлов


Чтобы получить ответ на вопрос: “Каким образом сливать упорядоченные 4-
ки, 8-ки, и т.п.?” следует изучить рисунок 12.2.
Для слияния двух последовательностей мы производим сравнение первых
элементов файлов B и С. Наименьший элемент следует в файл A, и процесс
повторяется вновь до тех пор, пока упорядоченные четвёрки не превратятся
в упорядоченные восьмёрки.

47
1) Файл B 2) Файл B

55 18 94 44 55 18 94 44 Файл A
Файл A
...
06

67 42 12 06 67 42 12
Файл C Файл C
3) Файл B 4) Файл B

55 18 94 44 Файл A
55 18 94 44 Файл A

06 12 06 12 42

67 42 67
Файл C Файл C

Рисунок 11-12.2. – Слияние двух последовательностей


Сортировка простым слиянием достаточно эффективна. Общее число
пересылок осуществляемых при полной сортировке файла
равно M  N  Log 2 N  . Число сравнений C по значению ещё меньше,
т.к. при копировании остатка последовательности сравнения не
производятся.
Хотя показатели сортировки слияния схожи с показателями
производительности пирамидальной сортировки, но сортировка слиянием
требует вдвое больше памяти (2*N), что затрудняет её использование для
больших массивов данных расположенных в ОЗУ.

Естественное слияние
В случае простого слияния мы ничего не выигрываем, если данные уже
частично рассортированы. На k-м проходе длина всех рассортированных
последовательностей уже меньше или равна 2k и их уже можно объединять.

Метод сортировки, при котором каждый раз сливаются две самые


длинные упорядоченные подпоследовательности называется
естественным слиянием.

Пусть исходная последовательность элементов задана в виде файла A. Кро-


ме того, у нас имеется два вспомогательных файла B и C. Каждый проход
алгоритма состоит из:
- Фазы распределения, которая распределяет серии из A в B и C.

48
- Фазы слияния, которая сливает серии из B и C в A.
Выполнение обеих фаз продемонстрировано на рисунке 12.3. Обратите
внимание на то, что как во время распределения, так и в момент слияния
алгоритм формирует упорядоченные подпоследовательности. Поэтому с
каждым проходом длины упорядоченных подпоследовательностей
увеличиваются, а их количество уменьшается.
Файл A

17 31 5 59 13 41 43 67 11 23 29 47 3 7 71 2 19 57 37 61

Файл B
Разделение 61 37 71 7 3 67 43 41 13 31 17
Слияние

Файл C
57 19 2 47 29 23 11 59 5

Файл A

61 57 37 19 2 71 47 29 23 11 7 3 67 59 43 41 13 31 17 5

Рисунок 11-12.3. – Демонстрация алгоритма естественного слияния

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. –
СПб.: Невский Диалект, 2013. – 352 с.: ил.
2. Осипов Д. Delphi XE2. СПб.: Издательство БХВ, – 2015. – 912 с.

Задания для развития и контроля владения компетенциями


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

49
13-14 Базовые алгоритмы на графах

Лабораторная работа – 4 часа

Цель занятия: исследование фундаментальных алгоритмов на графах.


Позволяет развить способность собрать и провести анализ исходных данных
для проектирования подсистем и средств обеспечения информационной без-
опасности (ПК - 18), способность использовать основные естественнонауч-
ные законы, применять математический аппарат в профессиональной дея-
тельности, выявлять сущность проблем, возникающих в ходе профессио-
нальной деятельности (ПК - 1) и способность использовать инструменталь-
ные средства и системы программирования для решения профессиональных
задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Какие алгоритмы используются для посещения всех узлов графа?
2. Что такое минимальное остовное дерево (МОД)?
3. Можно ли применять алгоритм МОД при поиске кратчайшего пу-
ти?
4. Что такое “жадный” алгоритм?
5. Какие способы поиска кратчайшего пути между двумя вершинами
графа вам известны?

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

50
еще непосещённый сосед, а затем двигаемся в этом новом направлении (см.
рис. 14.1).
1 2 3 1 2 3 1 2 3

7 8 7 8 7 8

9 9 9
тупик тупик
возврат
6 5 3 6 5 3 6 5 3

Шаг 1 Шаг 2 Шаг 3

Рисунок 13-14.1. – Иллюстрация алгоритма обхода в глубину


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

1 2 3 1 2 3 1 2 3

7 8 7 8 7 8
9 9 9
6 5 3 6 5 3 6 5 3

Шаг 1 Шаг 2 Шаг 3

Рисунок 13-14.2 – Иллюстрация алгоритма обхода по уровням

Построение минимального остовного дерева


Минимальным остовным деревом (МОД) связного взвешенного графа
называется его связный подграф, состоящий из всех вершин исходного
дерева и некоторых его ребер, причем сумма весов ребер минимально
возможная.
В конце 1950-х годов Эдгар Дейкстра и Прим, работая и публикуя свои
результаты независимо друг от друга, предложили следующий алгоритм
построения МОД. Разобьем вершины графа на три класса:
1. вершины, вошедшие в уже построенную часть дерева;
2. вершины, окаймляющие построенную часть;

51
3. еще не рассмотренные вершины.
Начнем с произвольной вершины графа и включим ее в остовное дерево (см.
рис. 10.3). Все вершины, соединенные с исходной вершиной, заносим в
кайму. Затем выполняется цикл поиска ребра с наименьшим весом,
соединяющего уже построенную часть остовного дерева с каймой. Это
ребро вместе с новой вершиной добавляется в дерево и происходит
обновление каймы. После того, как в дерево попадут все вершины, работа
будет закончена.
C
4 4 C
2 B
A B A 5
2 F A 5
4 7 6 3 F
4 C
C 5 D 8 E A 7
6 D 6 ...
1 6 5 D B D
6 7 3
6 B E
F G F 8
7
G E G
Исходные
данные Шаг 1 Шаг 2 Шаг 3

Рисунок 13-14.3. – Алгоритм построения МОД Дейкстры-Прима


Алгоритм Дейкстры-Прима начинает построение МОД с конкретной
вершины графа и постепенно расширяет построенную часть дерева. В
отличие от него алгоритм Крускала делает упор на ребрах графа. В этом
алгоритме мы начинаем с пустого дерева и добавляем к нему ребра в
порядке возрастания их весов пока не получим набор ребер, объединяющий
все вершины графа.
Если ребра закончатся до того, как все вершины будут соединены между
собой, то это означает, что исходный граф был несвязным, и полученный
нами результат представляет собой объединение МОД всех его компонент
связности.
На рисунке 10.4 представлены шаги алгоритма Крускала создающего МОД
для тех же исходных данных, что и в предыдущем примере.

52
2 2
A B A B A B
3

C D E C D E C D E
1 1 1

F G F G F G

Шаг 1 Шаг 2 Шаг 3

2 2 2
A B A B A B

4 3 4 3 4 3

C D E C D E C D E

1 1 1

G F 6 G
F F G

Шаг 4 Шаг 5 Шаг 6

Рисунок 13-14.4. – Иллюстрация алгоритма Крускала

Поиск кратчайшего пути


Результатом алгоритма поиска кратчайшего пути является
последовательность ребер, соединяющая две заданные вершины и имеющая
наименьшую длину среди всех таких последовательностей. Если изменить
рассмотренный ранее алгоритм Дейкстры-Прима построения МОД так,
чтобы при выборе ребра, ведущего в кайму, он выбирал ребро, являющееся
частью кратчайшего в целом пути из начальной вершины, то мы получим
требуемый результат. На этой идее и основан алгоритм Дейкстры.
Допустим, что нам требуется построить кратчайший путь из вершины A в
вершину G (см. рис. 14.5).

53
4 C
2 B
A B 7
2 A D
4 7 6 3
4 C 5
C 5 D 8 E A 7 2 F
1 6 5 D
6 7 B
3
6 E
F G F
8

4 C 4 C 4 C 4 C

7 7 7 7
A D A D A D A D
5 5 5 5
2 F 2 F
2 F 2 F

B
3 B
3 B
3 3
B
E E E E
8 8 8 8

G G G G

Рисунок 13-14.5. – Иллюстрация алгоритма Декстры при прокладке


кратчайшего пути из A в G
На каждой итерации алгоритма Дейкстры в кайму добавляется ребро с
наименьшим весом относительно стартовой вершины. Так как наш алгоритм
начинает работать из вершины A, то на первом шаге в кайму добавляется
ребро соединяющее узел А c узлом B, так как вес ребра самый малый. На
втором шаге мы анализируем веса рёбер исходящих уже из двух этих
вершин. “Победителем” становится ребро с весом 4, оно соединяет вершины
A и C. Ребро B-E будет добавлено в кайму только на третьем этапе,
заметьте, что при включении этого ребра в кайму следует учитывать
суммарный вес пути A-B-E=2+3=5.

Рекомендуемая литература
1. Седжвик. Р. Фундаментальные алгоритмы на C++. Анализ/Структуры
данных/Сортировка/Поиск: Пер. с англ./Роберт Седжвик. - К.:
Издательство «ДиаСофт», 2015.- 688 с.
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в
Delphi. Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.:
Питер, 2016 – 557 с.

54
3. Дональд Э. Кнут. Искусство программирования. Том 2. Основные
алгоритмы 3-е издание — СПб.:Вильямс, 2011.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


Для выполнения заданий воспользуйтесь программой хранения информации
об ориентированном графе, разработанной на лабораторной работе на тему
“Нелинейные структуры данных”.
1. Разработайте процедуры позволяющие посетить все узлы произвольного
графа, для этого воспользуйтесь алгоритмами обхода графа в глубину и
по уровням.
2. Используя алгоритмы Дейкстры-Прима и Крускала разработайте
процедуры строящие МОД произвольного графа.
3. Реализуйте алгоритм поиска кратчайшего пути в графе.

55
15 Алгоритмы сжатия данных без потерь

Лабораторная работа – 4 часа

Цель занятия: исследование методов сокращения избыточности дан-


ных. Позволяет развить способность собрать и провести анализ исходных
данных для проектирования подсистем и средств обеспечения информацион-
ной безопасности (ПК - 18), способность использовать основные естествен-
нонаучные законы, применять математический аппарат в профессиональной
деятельности, выявлять сущность проблем, возникающих в ходе профессио-
нальной деятельности (ПК - 1) и способность использовать инструменталь-
ные средства и системы программирования для решения профессиональных
задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. Что такое энтропия?
2. Какое условие определяет возможность сжатия данных без по-
терь?
3. Раскройте смысл метода “running”?
4. Принцип словарного метода сжатия?
5. Оказывает ли влияние размер словаря на степень сжатия данных?
6. На примере раскройте принцип работы алгоритма Хаффмана.

Методические рекомендации
Алгоритмы сжатия могут повышать эффективность хранения и передачи
данных посредством сокращения их избыточности.
Избыточность в представлении строки S есть L(S) - H(S), где L(S) есть длина
представления в битах, а H(S) – энтропия - мера содержания информации,
так же выраженная в битах. Алгоритмов, которые могли бы без потери
информации сжать строку к меньшему числу бит, чем составляет ее
энтропия, не существует.

Метод “Running”
Самый простой из методов упаковки информации называется “Running”.
Предположите, что вы имеете строку текста, и в конце строки стоит 40
пробелов. Налицо явная избыточность имеющейся информации. Проблема

56
сжатия этой строки решается очень просто – эти 40 пробелов (40 байт)
сжимаются в 3 байта с помощью упаковки их по методу повторяющихся
символов. Первый байт, стоящий вместо 40 пробелов в сжатой строке,
фактически будет являться пробелом (последовательность была из
пробелов). Второй байт – специальный байт "флажка" который указывает
что мы должны развернуть предыдущий в строке байт в
последовательность при восстановлении строки. Третий байт – байт счета
(в нашем случае это будет 40). Как вы сами можете видеть, достаточно
чтобы любой раз, когда мы имеем последовательность из более 3-х
одинаковых символов, заменять их выше описанной последовательностью,
чтобы на выходе получить блок информации меньший по размеру, но
допускающий восстановление информации в исходном виде.
Алгоритм Running эффективен только в ситуации, когда мы имеем
последовательность из более 3-х повторяющихся символов. В данном
методе основной проблемой является выбор того самого байта "флажка",
так как в реальных блоках информации как правило используются все 256
вариантов байта и нет возможности иметь 257 вариант - "флажок".

Словарные методы сжатия


Идея словарных методов заключается в замене строк символов на такие
коды, что их можно трактовать как индексы какого-то словаря.
Словарь – это набор таких фраз, которые как мы полагаем будут
встречаться в обрабатываемой последовательности.
Индексы должны быть построены таким образом, чтобы в среднем их
представление составляло меньше места чем требуют замещаемые строки.
Классический представитель словарных методов сжатия данных – алгоритм
LZW.
 LZW отказывается от 8-мибитного кодирования и, например,
переходит к 10-битному (2^10=1024). Значения кодов 0 - 255
соответствуют отдельным байтам, а коды 256 - 1024 соответствуют
подстрокам.
 В процессе кодирования LZW строит таблицу соответствия (словарь)
сочетание символов  числовое значение.
 Алгоритм LZW приступает к анализу исходной строки преобразуя
последовательность сочетаний символов в коды подстрок.
Полученные коды заносятся в таблицу соответствия.

57
Рассмотрим работу алгоритма на примере. Входная строка является кратким
списком слов, разделенных символом "/". Указанная строка состоит из 19
символов, что соответствует 19*8=152 битам.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

/ W E D / W E / W E E / W E B / W E T

Работа начинается с того, что на первом шаге цикла алгоритм выполняет


проверку на наличие строки "/W" в таблице словаря (см. табл. 16.1). Когда
он не находит эту строку, то генерирует код для "/" и добавляет в таблицу
строку "/W". Так как 256 символов уже определены для кодов 0 - 255, то
первой определенной строке может быть поставлен в соответствие код 256.
После этого система читает следующую букву ("E"), добавляет вторую
подстроку ("WE") в таблицу и выводит код для буквы "W".
Таблица 0.1. – Построение словаря для последовательности
Вход Выход Новые коды и со-
(символы) (коды) ответствующие
строки
/W / 256 = /W
E W 257 = WE
D E 258 = ED
/ D 259 = D/
WE 256 260 = /WE
/ E 261 = E/
WEE 260 262 = /WEE
/W 261 263 = E/W
EB 257 264 = WEB
/ B 265 = B/
WET 260 266 = /WET
<EOF> T

В результате работы алгоритма мы получаем строку из 12 символов, каждый


из которых занимает 10 бит:

1 2 3 4 5 6 7 8 9 10 11 12

/ W E D 256 E 260 261 257 B 260 T

58
Эффект от сжатия данных налицо, исходная строка занимала 152 бита, а
сжатая – 120 бит. В результате мы получили выигрыш превышающий 20%.
Теперь познакомимся с алгоритмом распаковки. Алгоритм распаковки
получает выходной поток кодов от алгоритма сжатия и использует его для
точного восстановления входного потока (см. табл. 16.2).
Таблица 0.2. – Алгоритм распаковки
Вход Старый Выход Символ Новый вход табли-
код цы
/ / /
W / W W 256 = /W
E W E E 257 = WE
D E D D 258 = ED
256 D /W / 259 = D/
E 256 E E 260 = /WE
260 E /WE / 261 = E/
261 260 E/ E 262 = /WEE
257 261 WE W 263 = E/W
B 257 B B 264 = WEB
260 B /WE / 265 = B/
T 260 T T 266 = /WET

Алгоритм Хаффмана
Алгоритм Хаффмана (англ. Huffman) – жадный алгоритм оптимального
префиксного кодирования алфавита с минимальной избыточностью. Этот
метод кодирования состоит из двух основных этапов:
1. Построение оптимального кодового дерева.
2. Построение отображения кодсимвол на основе построенного дерева.
Допустим, что мы имеем файл длинной в 100 символов и имеющий 6
различных символов в себе, обозначим их как: A, B, C, D, E и F. Мы
подсчитали вхождение каждого из символов в файл и получили следующее:

Символ C E B F A D
Число вхождений 30 25 20 10 10 5

59
Процесс формирования опти-
мального кодового дерева пред-
ставлен на рисунке 16.1. Симво-
лы с наименьшей вероятностью
появления (на первом этапе это
A и D) объединяют в новый
символ, вероятность которого
равна суммарной вероятности
этих символов. Затем удаляют
эти символы и вставляют новый
символ в список остальных на
соответствующее место (по ве-
роятности). Рисунок 0.1. – Построение оптимального кодового дерева
Далее в дереве находится
следующий символ (или пара символов) с наименьшей вероятностью
появления. Найденные символы вновь объединяются, и процесс повторяется
вновь, до полного построения
кодового дерева
Теперь, когда наше дерево
создано, мы можем кодировать
файл. Мы должны всегда начинать
из корня. Кодируя первый символ
(лист дерева С) Мы прослеживаем
вверх по дереву все повороты
ветвей и если мы делаем левый
поворот, то запоминаем 0-й бит, и
аналогично 1-й бит для правого
поворота (рис. 16.2).
Рисунок 0.2. – Кодирование файла
После кодирования мы получаем
следующие результаты:
- C = 00, занимает 2 бита;
- A = 0100 (4 бита);
- D = 0101 (4 бита);
- F = 011 (3 бита);
- B = 10 (2 бита);
- E = 11 (2 бита).
60
Эффективность алгоритма Хаффмана весьма высока. Каждый символ
изначально представлялся 8-ю битами (один байт), и так как мы уменьшили
число битов необходимых для представления каждого символа, мы
следовательно уменьшили размер выходного файла. Первоначальный
размер файла составлял: 100 байт - 800 бит. Размер сжатого файла: 30 байт -
240 бит, 240 - 30% из 800 , так что мы сжали этот файл на 70% (см. табл.
16.3).
Таблица 0.3. – Анализ результатов кодирования
Частота Первоначально Уплотненные Уменьшено
биты на
C – 30 30 x 8 = 240 30 x 2 = 60 180
A – 10 10 x 8 = 80 10 x 3 = 30 50
D–5 5 x 8 = 40 5 x 4 = 20 20
F – 10 10 x 8 = 80 10 x 4 = 40 40
B – 20 20 x 8 = 160 20 x 2 = 40 120
E – 25 25 x 8 = 200 25 x 2 = 50 150

Рекомендуемая литература
1. Седжвик. Р. Фундаментальные алгоритмы на C++. Анализ/Структуры
данных/Сортировка/Поиск: Пер. с англ./Роберт Седжвик. - К.:
Издательство «ДиаСофт», 2013.- 688 с.
2. Кормен. Т., Леверсон Ч., Ривест Р. Алгоритмы. Построение и анализ, 2-
е издание.: Пер. с англ. – М.: Издательский дом “Вильямс”, 2015. –
1296 с.: ил..
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


1. На основе метода “Running” разработайте алгоритм упаковки/распаковки
произвольной текстовой строки.
2. Используя идею алгоритма “LZW” разработайте функции, кодирующие и
декодирующие произвольную текстовую строку. Программа должна
позволять выбирать размерность кодирования (в пределах 10-16 бит).
Результаты работы программы представьте в табличном виде (см. табл.
13.1 и 13.2).

61
3. Реализуйте алгоритм Хаффмана кодирования произвольной текстовой
строки с алфавитом объёмом до 10 символов. Самостоятельно
предложите алгоритм декодирования файла.

62
16 Алгоритмы вывода графических примитивов

Лабораторная работа – 4 часа

Цель занятия: исследование простейших графических алгоритмов.


Позволяет развить способность собрать и провести анализ исходных данных
для проектирования подсистем и средств обеспечения информационной без-
опасности (ПК - 18), способность использовать основные естественнонауч-
ные законы, применять математический аппарат в профессиональной дея-
тельности, выявлять сущность проблем, возникающих в ходе профессио-
нальной деятельности (ПК - 1) и способность использовать инструменталь-
ные средства и системы программирования для решения профессиональных
задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуля-
ция.
Вопросы, выносимые на обсуждение:
1. В чём заключается недостаток метода прямого расчёта координат
отрезка?
2. Какая основная особенность инкрементных алгоритмов расчёта
координат пикселей вам известна?
3. Какие алгоритмы закрашивания областей вам известны?

Методические рекомендации
Вся растровая графика построена на идеи закрашивания элементарных
графических объектов – пикселей. В этом случае экран компьютера можно
рассматривать как двумерный массив пикселей, а операция рисования
является операцией заполнения элементов этого массива.
Например, в Delphi для закрашивания любого пикселя холста (класс TCan-
vas) применяется свойство:
property Pixels[X, Y: Integer]: TColor;
где X и Y – горизонтальная и вертикальная координата пикселя.
При графическом выводе стоит иметь в виду, что по умолчанию
координатное пространство Windows берёт начало в верхнем левом углу
окна. Ось X направлена слева направо, ось Y сверху вниз (см. рис. 18.1).

63
Рисунок 16.1. – Координатное пространство Windows

Рисование отрезка
Наиболее простейшим графическим примитивом считается прямая линия.
Действительно, что может быть элементарнее, чем вывод отрезка?
Проверим это утверждение.
Перед рассмотрением конкретных алгоритмов сформулируем общие
требования к изображению отрезка:
1. концы отрезка должны находиться в заданных точках;
2. отрезки должны выглядеть прямыми.
Предположим, что заданы координаты концов отрезка (x1,y1) и (x2,y2).
Если x1=x2 (вертикальная линия) или y1=y2 (горизонтальная линия), то для
вывода отрезка достаточно обращения к подобным строкам кода:

for y:=y1 to y2 do
Form1.Canvas.Pixels[x,y]:=clBlack;

Таким образом, вывод вертикальных или горизонтальных линий не пред-


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

64
Каким образом Windows принимает решение на закрашивание того или
иного пикселя при выводе линии? Поверьте, это совсем не праздный вопрос.
Судите сами. Если линия строго горизонтальна или вертикальна, то всё
ясно. Проводя отрезок из точки (1,10) в точку (1,100) пером единичной
толщины Windows не притрагиваясь к координате X, даёт последовательное
приращение координате Y. Задействуются точки: (1,10), (1,11), (1,12), …,
(1,99). Но какие пиксели потребуются для прорисовки наклонной линии,
допустим проходящей из точки (10,10) в точку (140,180)? С стопроцентной
точностью можно утверждать только то, что координаты первого
используемого пикселя равны (10,10). Определить координаты следующей
точки “на глаз” уже сложнее. Ими, с какой-то степенью вероятности, могут
оказаться пиксель (11,11) или пиксель (10,11). А о координатах 50-й по
счёту точки вообще допустимо говорить лишь приблизительно. Взгляните
на рисунок 14.2, на нём показано, что для вывода казалось идентичных
линий могут быть задействованы разные группы пикселей.

Рисунок 16.2. – Варианты вывода наклонной линии


Ни одно из требований к изображению отрезка не может быть точно выпол-
нено на растровом дисплее в силу того, что изображение строится из пиксе-
лей конечных размеров. Отрезок аппроксимируется набором пикселов и
лишь в частных случаях (вертикальный отрезок, горизонтальный отрезок,
отрезок под углом 45°) он будет выглядеть прямой, причем гладкой прямой,
без ступенек (рис. 14.2).

Прямое вычисление координат


Рассмотрим простейший способ вычисления координат закрашиваемых
пикселей. Пусть заданы координаты начальной (x1,y1) и конечной (x2,y2)
точек отрезка (см. рис. 14.3).

65
(0,0) x1 x x2

y1
y
y2

Рисунок 16.3. – Отрезок прямой


Запишем отношения катетов для подобных треугольников:
x  x1 x2  x1

y  y1 y2  y1 (18.1).

Тогда расчёт координат точки будет следующим:


x2  x1 y y
x  x1  ( y  y1 ) y  y1  ( x  x1 ) 2 1
y2  y1 (18.2), x2  x1 (18.3).

Положительные черты прямого вычисления координат сводятся к простоте


алгоритма и возможности работы с дробными значениями координат.
Недостатки рассмотренного метода более существенны. Во-первых,
использование операций с плавающей точкой, операций деления и
умножения обуславливают малую скорость алгоритма. Во-вторых,
растровый дисплей способен работать только с целыми числами, а
округление вещественных значений до целых вносит дополнительную
погрешность.
Для устранения недостатков алгоритмов прямого вычисления координат
придуманы инкрементные алгоритмы. Основной целью создания
инкрементного алгоритма было построение таких циклов вычислений
координат, чтобы в их основе лежали только целочисленные операции
сложения/вычитания.

Инкрементный алгоритм Брезенхэма


Инкрементные алгоритмы выполняются как последовательное вычисление
координат соседних пикселей путём добавления приращения координат.
Приращения рассчитываются на основе анализа функции погрешности.
Основная идея алгоритма Брезенхэма состоит в следующем. При черчении
виртуальной прямой из точки (x1,y1) в точку (x2, y2) перед принятием
решения на закрашивание очередного пикселя мы вычисляем угловой
коэффициент прямой. Если угловой коэффициент прямой меньше 0.5, то
66
естественно точку, следующую за точкой (0,0), поставить в позицию (1,0)
(рис. 18.4 а), а если угловой коэффициент больше 0.5, то - в позицию (1,1)
(рис. 18.4 б).

1 1

1 1

0,5

0 0

0 0
а) б)

Рисунок 16.4. – Исследование углового коэффициента прямой


Для принятия решения куда заносить очередной пиксель вводится величина
отклонения Е точной позиции от середины между двумя возможными
растровыми точками в направлении наименьшей относительной
координаты. Знак Е используется как критерий для выбора ближайшей
растровой точки.
Для демонстрации вычисления Е положим, что рассматриваемый вектор
начинается в точке (x1,y1)=(0,0) и проходит через точку (x2,y2)=(4,1.6), т.е.
имеет положительный наклон меньший 1 (см. рис. 18.5).

0,5

0,5

0 1 2 3 4

Рисунок 16.5. – Вектор начинается в точке (0,0) и проходит через точку (4,
1.6)
67
Из рисунка видно, отклонение для 1 шага: E1  Py / Px  1 / 2  0 , (где Py  y 2  y1
и Px  x2  x1 ) поэтому для занесения пикселя выбирается точка (1,0). Откло-
нение для 2 шага вычисляется добавлением приращения Y-координаты для
следующей X-позиции. E2  E1  Py / Px  0 поэтому для занесения пикселя
выбирается точка (2,1). Так как отклонение считается от Y-координаты, ко-
торая теперь увеличилась на 1, то из накопленного отклонения для вычис-
ления последующих отклонений надо вычесть единицу: E2  E2  1. Откло-
нение для третьего шага: E3  E2  Py / Px  0 поэтому для занесения пикселя
выбирается точка (3,1)., и т.д.
Ядро алгоритма Брезенхэма представлено в следующем листинге:

var X1,Y1,X2,Y2,X,Y:integer;
py,px,i,e : integer;
begin
X1:=10; Y1:=45; X2:=100; Y2:=80; //значения координат
X:=X1; Y:=Y1; Px:=X2 - X1; Py:=Y2 - Y1;
E:= 2*Py - Px;//можно заменить E:= Py+Py - Px;
i:= Px;
Form1.Canvas.Pixels[x,y]:=clBlack; //1-я точка вектора
while i>= 0 DO
begin
if (E >= 0) then
begin
INC(X); INC(Y);
E:= E + 2*(Py - Px);// можно написать так E:= E + (Py - Px)+ (Py - Px);
end else
begin
INC(X);
E:= E + 2*Py;//можно написать так E:=E+Py+Py
end;
Form1.Canvas.Pixels[x,y]:=clBlack; //очередная точка
DEC(I);
end;
end;

Этот алгоритм пригоден для случая 0 < dY < dX. Чтобы реализация
алгоритма Брезенхема была полной, необходимо обрабатывать отрезки во

68
всех октантах. Модификацию легко сделать, учитывая в алгоритме номер
квадранта, в котором лежит отрезок и его угловой коэффициент. Когда
абсолютная величина углового коэффициента больше 1, y постоянно
изменяется на единицу, а критерий ошибки Брезенхема используется для
принятия решения об изменении величины x. Выбор постоянно
изменяющейся (на +1 или -1) координаты зависит от квадранта (см. рис.
18.6).

Y
Увеличение X на 1
Уменьшение X на 1 Увеличение Y на 1
Увеличение Y на 1

x  x 1 x  x 1
y  y 1 y  y 1

x  x 1 x  x 1 X

y  y 1 y  y 1
Уменьшение X на 1 Увеличение X на 1
Уменьшение Y на 1 Уменьшение Y на 1

Рисунок 16.6. – Особенности обработки отрезков в разных квадрантах

Простейший алгоритм закрашивания замкнутой области


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

69
(0,0) X min X max X

Y min P3
P1

P2
X0 X1
P0

P4

Y max
P5

Рисунок 16.7. – Демонстрация алгоритма построчного заполнения


В таком случае нам подойдёт алгоритм построчного заполнения. Идея
основана на том, что соседние пиксели в строке скорее всего одинаковы и
меняются только там где строка пересекается с ребром многоугольника.
Алгоритм представляет собой цикл вдоль оси Y, в ходе цикла выполняется
поиск точек пересечения линии контура с соответствующими
горизонталями (см. рис. 14.7):
1. Найти самую нижнюю и самую верхнюю вершины.
2. Выполнить цикл от Y=Y min до Y max:
a. Нахождение точек xi пересечения всех отрезков контура с
горизонталью. Координаты этих точек занести в массив.
b. Сортировка массива точек по возрастанию x.
c. Вывод горизонтальных отрезков с координатами x0 , y   x1 , y  .

Рекомендуемая литература
1. Пореев В.Н. Компьютерная графика. – СПб.: БХВ-Петербург, 2014. –
432 с.: ил.
2. Майкл Ласло. Вычислительная геометрия и компьютерная графика на
C++: Пер. с англ. – М.: «Издательство БИНОМ», 2015. – 304 с. ил.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

70
Задания для развития и контроля владения компетенциями
1. Разработайте функцию позволяющую чертить произвольный отрезок
на основе прямого вычисления координат.
2. Разработайте функцию позволяющую чертить произвольный отрезок
на основе инкрементного алгоритма Брезенхэма.
3. Разработайте функцию позволяющую закрашивать произвольную
замкнутую область.
Для рисования замкнутой области можно воспользоваться методами Delphi.
Прямоугольник выводит процедура:
procedure Rectangle(Left, Top ,Right ,Bottom: Integer);
Эллипс чертит процедура:
procedure Ellipse(Left, Top ,Right ,Bottom: Integer);
Произвольный многоугольник с любым числом вершин:
procedure Polygon(Points: array of TPoint);
Например, многоугольник с пятью вершинами можно нарисовать с
помощью следующего кода:

var Arr : array [0..4] of TPoint;


begin
Arr[0]:=Point(10,10); Arr[1]:=Point(20,10); Arr[2]:=Point(120,45);
Arr[3]:=Point(120,200); Arr[4]:=Point(45,50);
Form1.Canvas.Polygon(Arr);
end;

71
Литература
1. Технология программирования: учебник/ Г.С. Иванова. —
М.:КНОРУС, 2013. — 336 с.
2. Скиена С. Алгоритмы. Руководство по разработке. — 2-е изд.: Пер. с
англ. — СПб.: БХВ-Петербург, 2014. — 720 с.: ил.
3. Технологии объектно-ориентированного программирования: учебник/
Хорев П.Б. — М.:Academia, 2015 — 448c.
4. Дональд Э. Кнут. Искусство программирования. Том 1. Основные ал-
горитмы 3-е издание — СПб.:Вильямс, 2014. — 720 с.
5. Дональд Э. Кнут. Искусство программирования, Том 2. Получисленные
алгоритмы 3-е издание— СПб.:Вильямс, 2013. — 832 с.
6. Кормен. Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ.—
М.; МЦНМО, 2016, 960 с.
7. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. –
СПб.: Невский Диалект, 2017. – 352 с.: ил.
8. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в
Delphi. Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.:
Питер, 2016 – 557 с.
9. Осипов Д. Delphi. Профессиональное программирование. Профессио-
нальное программирование. – СПб.: Символ-Плюс, 2016. – 1056 с.: ил.
10.Осипов Д. Графика в проектах Delphi. – СПб.: Символ-Плюс, 2013. –
648 с.: цв. ил.
11.Осипов Д. Delphi XE2. СПб.: Издательство БХВ, – 2013. – 912 с.
12.Луиза Тамре. Введение в тестирование программного обеспечения. –
М., Вильямс, 2013, 368 с.

72
Федеральное государственное автономное образовательное учреждение высшего
образования
Северо-Кавказский федеральный университет
Институт информационных технологий и телекоммуникаций

МЕТОДИЧЕСКИЕ УКАЗАНИЯ
ПО ВЫПОЛНЕНИЮ ПРАКТИЧЕСКИХ РАБОТ
по дисциплине «Технологии и методы программирования»
для бакалавров направления 10.03.01 «Информационная безопасность»

Ставрополь 2017 г.
1
Содержание
Содержание ............................................................................................................................. 2
Предисловие ............................................................................................................................ 3
1. Жизненный цикл и этапы разработки ПО ...................................................................... 5
Методические рекомендации ................................................................................................ 5
Каскадная модель .................................................................................................................. 9
Модель с промежуточным контролем ............................................................................... 10
Спиральная модель .............................................................................................................. 10
Рекомендуемая литература .................................................................................................. 13
Задания для развития и контроля владения компетенциями ............................................ 13
2. Спецификации при структурном подходе ..................................................................... 14
Методические рекомендации .............................................................................................. 14
Спецификации программного обеспечения при структурном подходе ........................ 14
Диаграммы переходов состояний ...................................................................................... 16
Функциональные диаграммы ............................................................................................. 17
Диаграммы потоков данных ............................................................................................... 19
Рекомендуемая литература .................................................................................................. 21
Задания для развития и контроля владения компетенциями............................................ 21
3. Методы анализа алгоритмов ............................................................................................ 22
Методические рекомендации .............................................................................................. 22
Рост функций ....................................................................................................................... 23
Рекомендуемая литература .................................................................................................. 24
Задания для развития и контроля владения компетенциями............................................ 24
4. Динамические структуры данных, связные списки .................................................... 26
Методические рекомендации .............................................................................................. 26
Списки .................................................................................................................................. 27
Пример создания и заполнения списка ............................................................................. 28
Рекомендуемая литература .................................................................................................. 29
Задания для развития и контроля владения компетенциями ............................................ 29
5. Улучшенные методы сортировки массивов .................................................................. 30
Методические рекомендации .............................................................................................. 30
Сортировка с помощью включений с уменьшающимися расстояниями (сортировка
Шелла) .................................................................................................................................. 30
Пирамидальная сортировка ................................................................................................ 31
Сортировка с разделением (быстрая сортировка) ............................................................ 34
Рекомендуемая литература .................................................................................................. 34
Задания для развития и контроля владения компетенциями ............................................ 35
6. Работа с последовательностями, файлы ........................................................................ 36
Методические рекомендации .............................................................................................. 36
Доступ к файлу .................................................................................................................... 37
Операции над файлами ....................................................................................................... 38
Окончание файла ................................................................................................................. 39
Пример работы с файлом .................................................................................................... 40
Рекомендуемая литература .................................................................................................. 41
Задания для развития и контроля владения компетенциями ............................................ 41
7. Нелинейные структуры данных ...................................................................................... 42
Методические рекомендации .............................................................................................. 42
Граф ...................................................................................................................................... 42
Бинарное дерево .................................................................................................................. 44
Рекомендуемая литература .................................................................................................. 44
Задания для развития и контроля владения компетенциями ............................................ 44
Литература .................................................................................................................................. 46

2
Предисловие
Дисциплина «Технологии и методы программирования» имеет целью обучить сту-
дентов принципам проектирования современного высокотехнологичного и безопасного
программного обеспечения. Дисциплина «Технологии и методы программирования» име-
ет также цель по формированию научного мировоззрения и развитию системного мышле-
ния.
Дисциплина «Технология и методы программирования», в соответствии с феде-
ральным государственным образовательным стандартом, является обязательной учебной
дисциплиной, входящей в базовую часть профессионального цикла.
Для успешного овладения дисциплиной обучаемые должны владеть знани-
ями и умениями полученными в ходе изучения дисциплин: «Логика», «Дискретная мате-
матика», «Информационные технологии» и «Языки программирования»
Дисциплина «Технологии и методы программирования» является базовой для изу-
чения таких учебных дисциплин, как «Программно-аппаратные средства защиты инфор-
мации», «Криптографические методы защиты информации», «Системы и сети передачи
информации», «Безопасность информационных систем» и др.
В результате успешного освоения дисциплины обучаемые приобретут следующие
компетенции:
 способностью применять программные средства системного, прикладного и специ-
ального назначения (ПК-15);
 способностью использовать инструментальные средства и системы программиро-
вания для решения профессиональных задач (ПК - 16);
 способностью к программной реализации алгоритмов решения типовых задач
обеспечения информационной безопасности (ПК-17).
Кроме того, обучающиеся должны:
знать:
 место и роль информационной безопасности в системе национальной безопасности
Российской Федерации;
 методы программирования и методы разработки эффективных алгоритмов решения
прикладных задач;
 современные средства разработки и анализа программного обеспечения на языках
высокого уровня;
 принципы организации информационных систем в соответствии с требованиями по
защите информации.
уметь:
 выбирать необходимые инструментальные средства для разработки программ в
различных операционных системах и средах;
 составлять, тестировать, отлаживать и оформлять программы на языках высо-
кого уровня, включая объектно-ориентированные;
 применять отечественные и зарубежные стандарты в области компьютерной без-
опасности для проектирования, разработки и оценки защищенности компьютерных
систем;
3
 пользоваться нормативными документами по защите информации.
владеть:
 основами информационной безопасности;
 специальной профессиональной терминологией;
 методами и средствами выявления угроз безопасности автоматизированным систе-
мам.

4
1. Жизненный цикл и этапы разработки ПО

Практическое занятие – 4 часа


Цель занятия: исследование основных этапов разработки современного программ-
ного обеспечения. Вырабатывает у обучаемого способность применять комплексный под-
ход к обеспечению информационной безопасности в различных сферах деятельности (ПК
- 30) и способность организовать работу малого коллектива исполнителей с учетом требо-
ваний защиты информации (ПК -31).
Организационная форма проведения занятия: круглый стол.
Вопросы, выносимые на обсуждение:
1. Что такое жизненный цикл ПО?
2. Что такое процесс разработки ПО?
3. Какие модели жизненного цикла ПО вам известны?
4. Что такое CASE-технология?

Методические рекомендации
Жизненным циклом программного обеспечения называют период от момента появ-
ления идеи создания некоторого программного обеспечения до момента завершения его
поддержки фирмой-разработчиком или фирмой, выполнявшей сопровождение.
Состав процессов жизненного цикла регламентируется международным стандартом
ISO/IEC 12207: 1995 «Information Technologe - Software Life Cycle Processes» («Информа-
ционные технологии - Процессы жизненного цикла программного обеспечения»), ISO -
International Organization for Standardization - Международная организация по стандарти-
зации. IEC - International Electrotechnical Commission - Международная комиссия по элек-
тротехнике.
Этот стандарт описывает структуру жизненного цикла программного обеспечения и
его процессы. Процесс жизненного цикла определяется как совокупность взаимосвязан-
ных действий, преобразующих некоторые входные данные в выходные. Каждый процесс
характеризуется определенными задачами и методами их решения, а также исходными
данными и результатами.
Процесс разработки (development process) в соответствии со стандартом предусмат-
ривает действия и задачи, выполняемые разработчиком, и охватывает работы по созданию
программного обеспечения и его компонентов в соответствии с заданными требованиями,
включая оформление проектной и эксплуатационной документации, а также подготовку
материалов, необходимых для проверки работоспособности и соответствия качества про-
граммных продуктов, материалов, необходимых для обучения персонала, и т. д.
По стандарту процесс разработки включает следующие действия:
 подготовительную работу - выбор модели жизненного цикла (см. далее), стандар-
тов, методов и средств разработки, а также составление плана работ;
 анализ требований к системе - определение ее функциональных возможностей,
пользовательских требований, требований к надежности и безопасности, требова-
ний к внешним интерфейсам и т. д.;

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

6
Указанные действия можно сгруппировать, условно выделив следующие основные этапы
разработки программного обеспечения (в скобках указаны соответствующие стадии раз-
работки по ГОСТ 19.102-77 «Стадии разработки»):
 постановка задачи (стадия «Техническое задание»);
 анализ требований и разработка спецификаций (стадия «Эскизный проект»);
 проектирование (стадия «Технический проект»);
 реализация (стадия «Рабочий проект»).
Традиционно разработка также включала этап сопровождения (началу этого этапа
соответствует стадия «Внедрение» по ГОСТ). Однако по международному стандарту в со-
ответствии с изменениями, происшедшими в индустрии разработки программного обес-
печения, этот процесс теперь рассматривается отдельно.
Условность выделения этапов связана с тем, что на любом этапе возможны вариан-
ты, которые потребуют пересмотра ранее принятых решений.
Постановка задачи. В процессе постановки задачи четко формулируют назначение
программного обеспечения и основные требования к нему. Каждое требование представ-
ляет собой описание необходимого или желаемого свойства программного обеспечения.
Различают функциональные требования, определяющие функции, которые должно вы-
полнять разрабатываемое программное обеспечение, и эксплуатационные требования, де-
кларирующие особенности его функционирования.
Требования к программному обеспечению, имеющему прототипы, обычно опреде-
ляют по аналогии, учитывая структуру и характеристики уже существующего программ-
ного обеспечения. Для формулирования требований к программному обеспечению, не
имеющему аналогов, иногда необходимо провести специальные исследования, называе-
мые предпроект- ными. В процессе таких исследований определяют разрешимость задачи,
возможно, разрабатывают методы ее решения (если они новые) и устанавливают наиболее
существенные характеристики разрабатываемого программного обеспечения. Для выпол-
нения предпроектных исследований, как правило, заключают договор на выполнение
научно-исследовательских работ. В любом случае этап постановки задачи заканчивается
разработкой технического задания, фиксирующего принципиальные требования, и приня-
тием основных проектных решений.
Анализ требований и определение спецификаций. Спецификациями называют точ-
ное формализованное описание функций и ограничений разрабатываемого программного
обеспечения. Соответственно различают функциональные и эксплуатационные специфи-
кации. Совокупность спецификаций представляет собой общую логическую модель про-
ектируемого программного обеспечения.
Для получения спецификаций выполняют анализ требований технического задания,
формулируют содержательную постановку задачи, выбирают математический аппарат
формализации, строят модель предметной области, определяют подзадачи и выбирают
или разрабатывают методы их решения. Часть спецификаций может быть определена в
процессе предпроектных исследований и соответственно зафиксирована в техническом
задании.
На этом этапе также целесообразно сформировать тесты для поиска ошибок в проек-
тируемом программном обеспечении, обязательно указав ожидаемые результаты.

7
Проектирование. Основной задачей этого этапа является определение подробных специ-
фикаций разрабатываемого программного обеспечения. Процесс проектирования сложно-
го программного обеспечения обычно включает:
 проектирование общей структуры - определение основных компонен¬тов и
их взаимосвязей;
 декомпозицию компонентов и построение структурных иерархий в соответ-
ствии с рекомендациями блочно-иерархического подхода;
 проектирование компонентов.
Результатом проектирования является детальная модель разрабатываемого про-
граммного обеспечения вместе со спецификациями его компонентов всех уровней. Тип
модели зависит от выбранного подхода (структурный, объектный или компонентный) и
конкретной технологии проектирования. Однако в любом случае процесс проектирования
охватывает как проектирование программ (подпрограмм) и определение взаимосвязей
между ними, так и проектирование данных, с которыми взаимодействуют эти программы
или подпрограммы.
Принято различать также два аспекта проектирования:
 логическое проектирование, которое включает те проектные операции, которые
непосредственно не зависят от имеющихся технических и про¬граммных средств,
составляющих среду функционирования будущего программного продукта;
 физическое проектирование - привязка к конкретным техническим и программным
средствам среды функционирования.
Реализация. Реализация представляет собой процесс поэтапного написания кодов
программы на выбранном языке программирования (кодирование), их тестирование и от-
ладку.
Сопровождение. Сопровождение - это процесс создания и внедрения новых версий
программного продукта. Причинами выпуска новых версий могут служить:
 необходимость исправления ошибок, выявленных в процессе эксплуатации
предыдущих версий;
 необходимость совершенствования предыдущих версий, например улучше-
ния интерфейса, расширения состава выполняемых функций или повыше-
ния его производительности;
 изменение среды функционирования, например появление новых техниче-
ских средств и/или программных продуктов, с которыми взаимодействует
сопровождаемое программное обеспечение.
На этом этапе в программный продукт вносят необходимые изменения, которые так
же, как в остальных случаях, могут потребовать пересмотра проектных решений, приня-
тых на любом предыдущем этапе. С изменением мо¬дели жизненного цикла программно-
го обеспечения (см. далее) роль этого этапа существенно возросла, так как продукты те-
перь создаются итерационно: сначала выпускается сравнительно простая версия, затем
следующая с большими возможностями, затем следующая и т. д. Именно это и послужило
причиной выделения этапа сопровождения в отдельный процесс жизненного цикла в со-
ответствии со стандартом ISO/IEC 12207.

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

Каскадная модель
Первоначально (1970-1985 годы) была предложена и использовалась каскадная схе-
ма разработки программного обеспечения (рис. 1.1), которая предполагала, что переход на
следующую стадию осуще¬ствляется после того, как полностью будут завершены про-
ектные операции предыдущей стадии и получены все исходные данные для следующей
ста¬дии. Достоинствами такой схемы являются:
 получение в конце каждой стадии законченного набора проектной до-кументации,
отвечающего требованиям полноты и согласованности;
 простота планирования процесса разработки.
Именно такую схему и используют обычно приблочно-иерархическом подходе к
разработке сложных технических объектов, обеспечивая очень высокие параметры эффек-
тивности разработки. Однако данная схема оказалась применимой только к созданию си-
стем, для которых в самом начале разработки удавалось точно и полно сформулировать
все требования. Это уменьшало вероятность возникновения в процессе разработки про-
блем, связанных с принятием неудачного решения на предыдущих стадиях. На практике
такие разработки встречаются крайне редко.

Рисунок 1.1. – Каскадная модель

В целом необходимость возвратов на предыдущие стадии обусловлена следующи-


ми причинами:
 неточные спецификации, уточнение которых в процессе разработки может
привести к необходимости пересмотра уже принятых решений;

9
 изменение требований заказчика непосредственно в процессе разработки;
 быстрое моральное устаревание используемых технических и программных
средств;
 отсутствие удовлетворительных средств описания разработки на стадиях
постановки задачи, анализа и проектирования.
Отказ от уточнения (изменения) спецификаций приведет к тому, что за-конченный
продукт не будет удовлетворять потребности пользователей. При отказе от учета смены
оборудования и программной среды пользователь получит морально устаревший продукт.
А отказ от пересмотра неудачных проектных решений приводит к ухудшению структуры
программного продукта и соответственно усложнит, растянет по времени и удорожит
процесс его создания. Реальный процесс разработки, таким образом, носит итерационный
характер.

Модель с промежуточным контролем


Схема, поддерживающая итерационный характер процесса разработки, была назва-
на схемой с промежуточным контролем (рис. 1.2). Контроль, который выполняется по
данной схеме после завершения каждого этапа, позволяет при необходимости вернуться
на любой уровень и внести необходимые изменения.
Основная опасность использования такой схемы связана с тем, что разработка ни-
когда не будет завершена, постоянно находясь в состоянии уточнения и усовершенствова-
ния.

Рисунок 1.2. – Схема разработки программного обеспечения с промежуточным контролем

Спиральная модель
Для преодоления перечисленных проблем в середине 80-х годов XX в. была предло-
жена спиральная схема (рис. 1.3). В соответствии с данной схемой программное обеспече-
ние создается не сразу, а итерационно с использованием метода прототипирования, бази-
рующегося на создании прототипов. Именно появление прототипирования привело к то-
му, что процесс модификации программного обеспечения перестал восприниматься как
«необходимое зло», а стал восприниматься как отдельный важный процесс.
Прототипом называют действующий программный продукт, реализующий отдель-
ные функции и внешние интерфейсы разрабатываемого программного обеспечения.

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

Постановка Анализ
задачи

Реализация Проектирование

Рисунок 1.3. - Спиральная или итерационная схема разработки программного обеспечения

Основной проблемой использования спиральной схемы является определение мо-


ментов перехода на следующие стадии. Для ее решения обычно ограничивают сроки про-
хождения каждой стадии, основываясь на экспертных оценках.
Изменение жизненного цикла программного обеспечения при использовании
CASE-технологий. CASE-технологии представляют собой совокупность методологий ана-
лиза, проектирования, разработки и сопровождения сложных программных систем, осно-
ванных как на структурном, так и на объектном подходах, которые поддерживаются ком-
плексом взаимосвязанных средств автоматизации. В основе любой CASE-технологии ле-
жит парадигма методология/метод/нотация/средство.

11
Методология строится на базе некоторого подхода и определяет шаги работы, их
последовательность, а также правила распределения и назначения методов. Метод опре-
деляет способ достижения той или иной цели - выполнение шага работы.
Нотацией называют систему обозначений, используемых для описания некоторого
класса моделей. Нотации бывают графические (предоставление моделей в виде графов,
диаграмм, таблиц, схем и т. п.) и текстовые (описания моделей на формальных и есте-
ственных языках). В CASE-технологиях нотации используют для описания структуры
проектируемой системы, элементов данных, этапов обработки и т. п.
Средства - инструментарий для поддержки методов: средства создания и редакти-
рования графического проекта, организации проекта в виде иерархии уровней абстракции,
а также проверки соответствия компонентов разных уровней. Различают:
 CASE-средства анализа требований, проектирования спецификаций и струк-
туры, редактирования интерфейсов (первое поколение CASE-I);
 CASE-средства генерации исходных текстов и реализации интегрированного
окружения поддержки полного жизненного цикла разработки программного
обеспечения (второе поколение CASE-II).
CASE-I в основном включают средства для поддержки графических моделей, проек-
тирования спецификаций, экранных редакторов и словарей данных. CASE-II отличается
существенно большими возможностями, обеспечивая: контроль, анализ и связывание си-
стемной информации и информации по управлению процессом проектирования, построе-
ние прототипов и моделей системы, тестирование, верификацию и анализ сгенерирован-
ных программ.
Автоматизируя трудоемкие операции, современные CASE-средства существенно по-
вышают производительность труда программистов и улучшают качество создаваемого
программного обеспечения:
 обеспечивают автоматизированный контроль совместимости спецификаций
проекта;
 уменьшают время создания прототипа системы;
 ускоряют процесс проектирования и разработки;
 автоматизируют формирование проектной документации для всех этапов
жизненного цикла в соответствии с современными стандартами;
 частично генерируют коды программ для различных платформ разработки;
 поддерживают технологии повторного использования компонентов систе-
мы;
 обеспечивают возможность восстановления проектной документации по
имеющимся исходным кодам.
Появление CASE-технологий изменило все этапы жизненного цикла программного
обеспечения, при этом наибольшие изменения касаются анализа и проектирования, кото-
рые предполагают строгое и наглядное описание разрабатываемого программного обеспе-
чения.

12
Рекомендуемая литература
1. Технология программирования: учебник/ Г.С. Иванова. — М.:КНОРУС,
2011. — 336 с.
2. Технологии объектно-ориентированного программирования: учебник/ Хорев
П.Б. — М.:Academia, 2008 — 448c.
Интернет-ресурсы
1. Материалы сайта корпорации Microsoft http://www.microsoft.ru
2. Материалы сайта компании Embarcadero http://www.embarcadero.ru

Задания для развития и контроля владения компетенциями


Учебная группа разделяется на коллективы по 5-6 студентов. В составе коллектива
выбирается:
 руководитель проекта,
 программисты;
 разработчик технической документации;
 тестировщик программного обеспечения.

На коллектив студентов преподаватель выдаёт задание:


1. разработать программу “Калькулятор”;
2. разработать программу “Блокнот”;
3. разработать программу “Адресная книга”;
4. разработать программу “Дни рождений”;
5. разработать программу “Телефонный справочник”.
В соответствии с полученным вариантом коллектив формирует техническое задание на
проектирование ПО.

13
2. Спецификации при структурном подходе

Практическое занятие – 4 часа

Цель занятия: исследование порядка разработки программного обеспечения на ос-


нове структурного подхода. Вырабатывает у обучаемого способность использовать ос-
новные естественнонаучные законы, применять математический аппарат в профессио-
нальной деятельности, выявлять сущность проблем, возникающих в ходе профессиональ-
ной деятельности (ПК - 1), способностью применять комплексный подход к обеспечению
информационной безопасности в различных сферах деятельности (ПК - 30).
Организационная форма проведения занятия: круглый стол.
Вопросы, выносимые на обсуждение:
1. Что такое спецификация разрабатываемого ПО?
2. Роль диаграмм переходов в разработке ПО?
3. Что представляет собой функциональные диаграммы?
4. При решении каких задач следует применять диаграммы потоков данных?
5. Что такое структурный подход при разработке ПО?

Методические рекомендации
Спецификации программного обеспечения при структурном подходе
Спецификации представляют собой полное и точное описание функций и
ограничений разрабатываемого программного обеспечения. При этом одна часть
спецификаций (функциональные) описывает функции разрабатываемого программного
обеспечения, а другая часть (эксплуатационные) определяет требования к техническим
средствам, надежности, информационной безопасности и т. д.
Определение отражает главные требования к спецификациям. Применительно к
функциональным спецификациям подразумевается, что:
− требование полноты означает, что спецификации должны содержать всю
существенную информацию, где ничего важного не было бы упущено, и
отсутствует несущественная информация, например детали реализации, чтобы
не препятствовать разработчику в выборе наиболее эффективных решений;
− требование точности означает, что спецификации должны однозначно
восприниматься как заказчиком, так и разработчиком.
Последнее требование выполнить достаточно сложно в силу того, что естественный
язык для описания спецификаций не подходит: даже подробные спецификации на
естественном языке не обеспечивают необходимой точности. Точные спецификации
можно определить, только разработав некоторую формальную модель разрабатываемого
программного обеспечения.
Формальные модели, используемые на этапе определения спецификаций можно
разделить на две группы: модели, зависящие от подхода к разработке (структурного или
объектно-ориентированного), и модели, не зависящие от него. Так диаграммы переходов
состояний, которые демонстрируют особенности поведения разрабатываемого

14
программного обеспечения при получении тех или иных сигналов извне, и математичес-
кие модели предметной области используют при любом подходе к разработке.
В рамках структурного подхода на этапе анализа и определения спецификаций
используют три типа моделей: ориентированные на функции, ориентированные на
данные и ориентированные на потоки данных. Каждую модель целесообразно
использовать для своего специфического класса программных разработок.
Поскольку разные модели описывают проектируемое программное обеспечение с
разных сторон, рекомендуется использовать сразу несколько моделей и сопровождать их
текстами: словарями, описаниями и т. п., которые поясняют соответствующие диаграммы.
Так методологии структурного анализа и проектирования, основанные на
моделировании потоков данных, обычно используют комплексное представление
проектируемого программного обеспечения в виде совокупности моделей:
− диаграмм потоков данных (DFD - Data Flow Diagrams), описывающих
взаимодействие источников и потребителей информации через процессы, которые
должны быть реализованы в системе;
− диаграмм «сущность-связь» (ERD - Entity-Relationship Diagrams), описывающих
базы данных разрабатываемой системы;
− диаграмм переходов состояний (STD - State Transition Diagrams), характеризующих
поведение системы во времени;
− спецификаций процессов;
− словаря терминов.

Рисунок 2.1. - Элементы полной спецификации методологий структурного анализа и


проектирования программного обеспечения, основанных на потоках данных

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

Условие
Имя
состояния Действие

Терминальное Промежуточное
Переход
состояние состояние

Рисунок 2.2. - Условные обозначения, используемые при построении диаграмм переходов


состояний

Если программная система в процессе функционирования активно не взаимодействует


с окружающей средой (пользователем или датчиками), например, использует
примитивный интерфейс и выполняет некоторые вычисления по заданным исходным
данным, то диаграмма переходов состояний обычно интереса не представляет. В этом
случае она демонстрирует только последовательно выполняемые переходы: из исходного
состояния в состояние ввода данных, затем после выполнения вычислений - в состояние
вывода и, наконец, в состояние завершения работы (рис. 3.3).
Исходное Состояние
состояние завершения

Ввод Вывод

Всегда Всегда Всегда


Инициализация Вычисление Завершение

Рисунок 2.3. – Пример простейшей диаграммы переходов

Для интерактивного программного обеспечения с развитым пользовательским


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

16
наличие состояния ожидания, когда программное обеспечение приостанавливает работу
до получения очередного управляющего воздействия. Для интерактивного программного
обеспечения наиболее характерно получение команд различных типов (рис. 3.4), а если
это еще и программное обеспечение реального времени - однотипных сигналов (либо от
многих датчиков, либо требующих продолжительной обработки).
Исходное Состояние
состояние завершения

Всегда Всегда
Инициализация Завершение

Ожидание

Воздействие1 Воздействие2 Воздействие3


Функция 1 Функция 2 Функция 3

Рисунок 2.4. – Пример диаграммы переходов с состоянием ожидания

Функциональные диаграммы
Функциональными называют диаграммы, в первую очередь отражающие взаимосвязи
функций разрабатываемого программного обеспечения. В качестве примера
функциональной модели рассмотрим активностную модель, предложенную Д. Россом в
составе методологии функционального моделирования SADT (Structured Analysis and De-
sign Technique - технология структурного анализа и проектирования) в 1973 г..

Отображение взаимосвязи функций активностной модели осуществляется


посредством построения иерархии функциональных диаграмм, схематически
представляющих взаимосвязи нескольких функций. Каждый блок такой диаграммы
соответствует некоторой функции, для которой должны быть определены: исходные
данные, результаты, управляющая информация и механизмы ее осуществления - человек
или технические средства.
Все перечисленные выше связи функции представляются дугами, причем тип связи и
ее направление строго регламентированы. Дуги, изображающие каждый тип связей,
должны подходить к блоку с определенной стороны (рис. 3.5), а направление связи
должно указываться стрелкой в конце дуги.

17
Управление

Результаты
Исходные
данные Функция

Механизм

Рисунок 2.5. – Пример расположения дуг на диаграмме

Физически дуги исходных данных, результатов и управления представляют собой


наборы данных, передаваемые между функциями. Дуги, определяющие механизм
выполнения функции - исполнителей-людей или соответствующие технические средства,
в основном используют при описании спецификаций сложных информационных систем,
которые включают как автоматизированные, так и ручные операции. Блоки и дуги
маркируются текстами на естественном языке.
Блоки на диаграмме размещают по «ступенчатой» схеме в соответствии с
последовательностью их работы или доминированием, которое понимается как влияние,
оказываемое одним блоком на другие. В функциональных диаграммах SADT различают
пять типов влияний блоков друг на друга:
− вход - выход блока подается на вход блока с меньшим доминированием, т. е.
следующего (рис. 3.6, а);
− управление - выход блока используется как управление для блока с меньшим
доминированием (следующего) (рис. 3.6, б);
− обратная связь по входу - выход блока подается на вход блока с большим
доминированием (предыдущего) (рис. 3.6, в);
− обратная связь по управлению - выход блока используется как управляющая
информация для блока с большим доминированием (предыдущего) (рис. 3.6,
г);
− выход-исполнитель - выход блока используется как механизм для другого
блока (рис. 3.6, д).

18
Функция1
Функция1 Функция2
Функция2
а) ввод б) управление

Функция1 Функция2
Функция1 Функция2

г) обратная связь по
в) обратная связь по входу
управлению

Функция2

Функция1

в) выход-исполнитель

Рисунок 2.6. – Типы влияний блоков

Построение иерархии функциональных диаграмм ведется поэтапно с увеличением


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

Диаграммы потоков данных


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

19
В основе модели лежат понятия внешней сущности, процесса, хранилища
(накопителя) данных и потока данных.
Внешняя сущность - материальный объект или физическое лицо, выступающие в
качестве источников или приемников информации, например заказчики, персонал,
поставщики, клиенты, банк и т. п.
Процесс - преобразование входных потоков данных в выходные в соответствии с
определенным алгоритмом. Каждый процесс в системе имеет свой номер и связан с
исполнителем, который осуществляет данное преобразование. Как в случае
функциональных диаграмм, физически преобразование может осуществляться
компьютерами, вручную или специальными устройствами. На верхних уровнях
иерархии, когда процессы еще не определены, вместо понятия «процесс» используют
понятия «система» и «подсистема», которые обозначают соответственно систему в целом
или ее функционально законченную часть.
Нотация Иордана Нотация Гейна-Сарсона

Номер
Наименование
Наименование
Наименование

Номер

Наименование
Наименование
Номер

Механизм

Наименование № Наименование

Наименование Наименование

Рисунок 2.7. – Условные обозначения диаграмм потоков данных

Хранилище данных - абстрактное устройство для хранения информации. Тип


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

20
детализируют. Физически это может быть база данных, файл, таблица в оперативной
памяти, картотека на бумаге и т. п.
Поток данных - процесс передачи некоторой информации от источника к приемнику.
Физически процесс передачи информации может происходить по кабелям под
управлением программы или программной системы или вручную при участии устройств
или людей вне проектируемой системы.
Для изображения диаграмм потоков данных традиционно используют два вида
нотаций: нотации Иордана и Гейна-Сарсона (рис. 3.7).

Рекомендуемая литература
1. Технология программирования: учебник/ Г.С. Иванова. — М.:КНОРУС,
2011. — 336 с.
2. Технологии объектно-ориентированного программирования: учебник/ Хорев
П.Б. — М.:Academia, 2008 — 448c.
Интернет-ресурсы
1. Материалы сайта корпорации Microsoft http://www.microsoft.ru
2. Материалы сайта компании Embarcadero http://www.embarcadero.ru

Задания для развития и контроля владения компетенциями


Учебная группа разбивается на коллективы по 3-4 человека. Каждому коллективу
студентов даётся задание на проектирование диаграмм перехода состояний, функцио-
нальных диаграмм и диаграмм потоков данных. Например:
− Разработать спецификации программы построения таблиц/графиков функций од-
ной переменной.
− Разработать спецификации программы учёта успеваемости студентов.
− Разработать спецификации программы игры в “крестики-нолики”.
По завершению разработки диаграммы студенческие коллективы обмениваются
своими работами с целью взаимного контроля.

21
3. Методы анализа алгоритмов

Практическое занятие – 4часа

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


обучаемого способность применять методы анализа изучаемых явлений, процессов и про-
ектных решений (ПК - 20).
Организационная форма проведения занятия: компьютерная симуляция.
Вопросы, выносимые на обсуждение:
1. Что такое алгоритм?
2. Какие качества должны быть у алгоритма?
3. Какие основные методы оценки качества алгоритмов вам известны?
4. Что такое основной параметр алгоритма?
5. Какие функции оценки производительности алгоритма вам известны?

Методические рекомендации
Алгоритм (algorithm) – это любая корректно определённая вычислительная процедура, на
вход которой подаётся некоторый набор значений, и результатом выполнения которой
является выходной набор значений.
Хороший алгоритм обладает следующими качествами:
- Конечность. Алгоритм всегда должен заканчиваться после выполнения конечного
числа шагов.
- Определённость. Каждый шаг алгоритма должен быть определён.
- Ввод. Каждый алгоритм имеет некоторое подмножество входных данных.
- Вывод. У алгоритма есть одно или несколько выходных данных.
- Эффективность. Алгоритм можно считать эффективным если все его операторы
достаточно просты чтобы их можно было выполнить в течении конечного
промежутка времени.
Прежде чем говорить об эффективности алгоритма необходимо убедиться, что он
предоставляет правильное решение!

Один из первых шагов в понимании производительности алгоритмов – это эмпирический


анализ. Например, если имеется два алгоритма способные решить одну и ту же задачу.
Мы их запускаем и сравниваем время их выполнения.
Самым простым способом сравнения времени выполнения алгоритма может стать
использование двух меток времени T1 и T2. Одна из них берётся в начале выполнения
алгоритма, а вторая в конце. Разность T2 - T1 и есть время выполнения.
Метку времени можно получить с помощью функций:
function Time: TDateTime;
function GetTime: TDateTime;

22
Обе функции идентичны, они возвращают системное время вашего компьютера.
Кроме того, в нашем распоряжении имеется системная функция Windows:
function GetTickCount: DWORD;

которая возвращает количество миллисекунд прошедших с начала запуска компьютера.


Её также можно применять для сравнения времени выполнения алгоритмов.

Математический анализ алгоритмов сводится к следующим действиям:


1. Выявление абстрактных операций из которых состоит алгоритм.
2. Определение частоты (количества раз) выполнения операций.
3. Моделирование данных поступающих на вход алгоритма

Рост функций
Большинство алгоритмов имеет главный параметр N, который значительно влияет на
степень его выполнения. Например: степень полинома, размер файла при сортировке или
поиске, количество символов в строке, и т.п. В большинстве случаев время выполнения
алгоритма можно свести функциям представленным в таблице 5.1.

Таблица 3.1. – Оценочные функции


Функция Описание Примечание
1 Время выполнения программы постоянно.
LogN Время выполнения программы является логарифми-
ческим
N Время выполнения программы является линейным

NLogN Время выполнения программы пропорциональное N


Log N

N2 Время выполнения программы является квадратич- Алгоритмы с такими по-


ным казателями не могут счи-
Время выполнения программы является кубическим таться эффективными!
N3
2N Время выполнения программы экспоненциально

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


одного взгляда на представленный на рисунке 5.1 график. Заметьте, что в качестве
параметра нами взята совсем небольшая величина N=20. Задумайтесь, что произойдет,
если главный параметр функций составит более существенные значения. Например, в
этом учебном пособии около 200 тысяч знаков. Чтобы было, если бы мы попытались
найти все вхождения слова “алгоритм” в нашем материале самым неэффективным
способом – алгоритмом грубой силы, оцениваемым N 2 ? В этом случае нам потребуется
около полутора миллионов операций сравнения! Если же мы воспользуемся алгоритмом
Бойера-Мура, то мы сможем сократить число сравнений на 25…40 процентов!

23
400
N
Log(N)
350 NLog(N)
N2
N2

300

250

200

150

100

50
NLog(N)

Log(N) N
0
0 2 4 6 8 10 12 14 16 18 20
N

Рисунок 3.1. – Сравнительная оценка функций

Алгоритм, претендующий на высокое эффективного должен стремится к оценочной


логарифмическим оценочным функциям.

Рекомендуемая литература
1. Дональд Э. Кнут. Искусство программирования. Том 1. Основные алгоритмы 3-е
издание — СПб.:Вильямс, 2011. — 720 с.
2. Кормен. Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ.—М.;
МЦНМО, 2006, 960 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


1. Разработайте две процедуры поиска наибольшего общего делителя (НОД)
произвольных чисел A и B. Первая процедура должна применять “лобовой” поиск
(обычный перебор). Вторая процедура может использовать любой известный вам
алгоритм поиска НОД, например алгоритм Евклида.
Подсказка:
Алгоритм Евклида. Дано два целых положительных числа а и b. Требуется найти
наибольшее целое положительное число, которое разделит числа а и b без остатка.
1. Находим остаток. Разделим a на b и получим остаток от деления r для
которого выполняется условие 0  r  b .

24
2. Сравнение с нулём. Если r=0, то b есть искомое число. Выполнение алгоритма
прекращается.
3. Замещение. Если r  0 , то заменим пару чисел (a, b) парой (b, r) и перейдем к
шагу 1.
При вычислении наибольшего общего делителя (a, b) с помощью алгоритма
Евклида будет выполнено не более 5N операций деления с остатком, где N есть
количество цифр в десятичной записи меньшего из чисел a и b.
2. Разработайте две процедуры получения факториала произвольного целого числа.
Первая процедура основана на классическом решении, а вторая на формуле Джеймса
Стирлинга:
n
n
n! 2n   ,
e
где: e – основание натурального алгоритма.
3. Разработайте две процедуры получения числа Фибоначчи. Первая процедура
вычисляет запрошенное число с помощью классического рекуррентного соотношения:

F0  0, F1  1, Fi  Fi1  Fi2 , i  2 .

Например: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … Вторая процедура получает число


Фибоначчи с помощью значения золотого сечения  и сопряжённого с ним значения  S :

1 5 S 1 5
 ,  .
2 2

В этом случае число Фибоначчи можно рассчитать с помощью выражения:

i  S
Fi  ,
5
после округления Fi до ближайшего целого числа.

После выполнения всех заданий проведите эмпирический и математический


сравнительный анализ ваших алгоритмов.

25
4. Динамические структуры данных, связные
списки

Практическое занятие – 6 часа

Цель занятия: исследование организации и способов представления в памяти дина-


мических структур данных. Позволяет развить способность собрать и провести анализ ис-
ходных данных для проектирования подсистем и средств обеспечения информационной
безопасности (ПК - 18).
Организационная форма проведения занятия: компьютерная симуляция.
Вопросы, выносимые на обсуждение:
1. Что такое указатель?
2. Какой объём памяти отводится для хранения указателя?
3. Для чего необходима структура данных “список”?
4. Что понимается под связным списком?
5. Какие разновидности связных списков вам известны?

Методические рекомендации
Любая переменная представляет собой ни что иное, как область памяти, содержащую ка-
кие то данные. Когда мы объявим переменную MyValue : integer, то в памяти компьюте-
ра будет зарезервировано 4 байта для хранения значения этой переменной. Содержимое
переменной MyValue можно просмотреть непосредственно в этой области памяти. Объ-
явив какую-нибудь другую переменную, мы заставим операционную систему отвести
под эту переменную новые свободные ячейки памяти. Соответственно значения указате-
лей на MyValue и новую переменную будут различны.
Динамические структуры по определению характеризуются отсутствием
физической смежности элементов структуры в памяти, непостоянством и
непредсказуемостью размера (числа элементов) структуры в процессе ее обработки.
Указатель представляет собой переменную, содержащую адрес области памяти.
Поскольку указатель хранит не содержимое памяти, а адрес к ячейкам памяти. Поэтому
он сам не занимает никакого места, кроме того, что нужно для хранящегося в нём адреса.
На практике работа с указателем выглядит следующим образом:

var MyValue : integer;


pMyValue : pointer;
begin
MyValue:=100;
pMyValue:=@MyValue; // указателю присвоен адрес переменной MyValue
end;

Обратите внимание на то, что при операции присвоения адреса указателю – перед
названием переменной установлен символ “@”. Теперь, дабы увидеть данные,
хранящиеся в MyValue (допустим у нас существует переменная i : Integer и мы хотим
26
через указатель передать ей данные из переменной MyValue) воспользуемся
следующими строками кода:

i:=INTEGER(pmyValue^);

Эквивалентом оператора @ служит метод:


function Addr(X): Pointer;

Функция возвращает указатель на объект X.


Тип данных Pointer называют нетипизированным указателем, так как он может указывать
на переменную любого типа. Очень часто применяют типизированные указатели,
которые способны работать с переменными определённого типа. Объявление такого
указателя выглядит следующим образом:

var pInt:^integer;

Рассмотрим ещё один небольшой пример:

var pInt : ^integer;


MyValue : integer;
begin
MyValue:=100; //целочисленной переменной присвоено значение 100
pInt :=Addr(MyValue); //указатель установлен в область памяти, где
хранится MyValue
pInt^ :=123; //в область памяти записано значение 123
end;

Результатом данного упражнения стало изменение значения переменной MyValue без


обращения к ней.

Если указатель пуст (ссылается “в никуда”), то он возвращает особое значение nil.


Пустой указатель называют неопределённым. В языке Delphi nil – специальная
константа, предназначенная для описания пустых (несуществующих) данных.

Списки

Наиболее простым способом связать (соединить) множество элементов это расположить


их линейно в списке или очереди.

Списком называется упорядоченное множество, состоящее из переменного числа


элементов, к которым применимы операции включения, исключения.

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

27
type pItem=^TItem;
TItem = Record
Data:Integer; //поле данных
P:Pointer; //поле связок
end;

В зависимости от стоящих перед программистом задач в качестве поля данных может


быть использована любая другая произвольная структура.
Идея построения односвязного списка представлена на рисунке 7.1. Обратите внимание
на то, что поле связок последнего элемента не имеет ссылки на другой элемент, поэтому
здесь находится неопределённый указатель nil.

Данные 1 Данные 2 Данные 3 nil

Рисунок 4.1 – Структура односвязного списка

Однако, обработка односвязного списка не всегда удобна, так как отсутствует


возможность продвижения в противоположную сторону. Такое положение вещей
исправляется введением дополнительного указателя на предыдущий элемент в списке.
Структуру двусвязного списка вы найдёте на рисунке 7.2.

Данные 1 nil Данные 2 Данные 3 nil

Рисунок 4.2. - Структура двусвязного списка

Для выделения памяти одному элементу списка следует воспользоваться процедурой:


procedure New(var P: Pointer);
В процедуре имеется единственный параметр P в который будет возвращён указатель на
созданный в памяти элемент.
Для уничтожения элемента вам пригодится процедура:
procedure Dispose(var P: Pointer);

Процедура освободит ранее выделенную память на которую ссылается указатель P.

Пример создания и заполнения списка


Рассмотрите пример создания списка из нескольких элементов.

var pFirstItem: pItem; //глобальная переменная

Procedure CreateList; //процедура создания списка


var pTempItem:pItem;
begin
Randomize;
New(pFirstItem); //создаём первый элемент списка
{теперь указатель pFirstItem будет нашим связным со всем списком}

28
pFirstItem^.Data:=Random(100);//передаём случайное значение в поле
данных
//============================================================
New(pTempItem); //создаём новый элемент списка
//передаём полученный указатель в предыдущий элемент
pFirstItem^.P:=pTempItem;
pTempItem^.Data:=Random(100);
end;

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. – СПб.:
Невский Диалект, 2007. – 352 с.: ил.
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в Delphi.
Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.: Питер, 2006 – 557 с.
3. Кормен. Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ.—М.;
МЦНМО, 2006, 960 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


1. Разработайте программу, позволяющую хранить целочисленные данные в формате
односвязного списка. Программа должна позволять пользователю:
 Создавать список.
 Добавлять элемент в конец списка.
 Вставлять элемент в произвольное место списка.
 Удалять любой элемент из списка.
 Читать данные из списка.
 Уничтожать весь список.
2. Разработайте программу, позволяющую хранить целочисленные данные в формате
двусвязного списка. Реализуйте в вашей программе те же функции, что и в первом
задании.

29
5. Улучшенные методы сортировки массивов

Практическое занятие – 6часа

Цель занятия: исследование эффективных методов сортировки одномерных масси-


вов. Позволяет развить способность собрать и провести анализ исходных данных для про-
ектирования подсистем и средств обеспечения информационной безопасности (ПК - 18) и
способность использовать основные естественнонаучные законы, применять математиче-
ский аппарат в профессиональной деятельности, выявлять сущность проблем, возникаю-
щих в ходе профессиональной деятельности (ПК - 1).
Организационная форма проведения занятия: компьютерная симуляция.
Вопросы, выносимые на обсуждение:
1. В чём заключается принципиальное отличие простейших и улучшенных ме-
тодов сортировки массивов?
2. Как оценивается эффективность алгоритма сортировки?
3. Что понимается под медианным элементом в алгоритме быстрой сортировки?

Методические рекомендации
Анализ всех простейших методов сортировки показывает, что сортировка обменом и её
небольшие улучшения хуже, чем сортировка включениями или выбором. Единственное
преимущество сортировки пузырьком – легко запоминающееся название. Алгоритм
Шейкер-сортировки выгодно применять лишь в редких случаях (когда массив частично
упорядочен).
Все рассмотренные в предыдущей работе алгоритмы относятся к классу N2. Во многом
такой плохой показатель определяется тем, что простые алгоритмы на каждом шаге чаще
всего перемещают элементы на одну позицию. Сегодня мы рассмотрим алгоритмы,
перемещающие данные за один цикл на большее расстояние.

Сортировка с помощью включений с уменьшающимися расстояниями (сортировка


Шелла)
В 1959 году Дональд Л. Шелл предложил улучшение сортировки простыми
включениями. Сортировка получила название сортировки включениями с убывающим
приращением или сортировки Шелла.
Сортировка Шелла представляет собой несколько этапов сортировок, каждая из которых
программируется, как классическая сортировка включениями. На рисунке 9.1
представлен процесс сортировки массива из 8-ми элементов способом Шелла.

30
4-сортировка 44 55 12 42 94 18 06 67

2-сортировка 44 18 06 42 94 55 12 67

1-сортировка 06 18 44 42 12 55 94 67

06 12 18 42 44 55 67 94

Рисунок 5.1. – Сортировка Шелла

На первом проходе отдельно группируются и сортируются элементы отстоящие друг от


друга на 4 позиции. После этого элементы объединяются в группы отстоящие друг от
друга на 2 позиции и сортируются заново. На 3-м проходе элементы сортируются
обычной сортировкой включениями.
Сначала может показаться, что необходимость в нескольких проходах сортировки в
каждом из которых участвуют все элементы, потребует больше работы чем сэкономит.
Однако на каждом шаге сортировки либо участвует мало элементов, либо они уже
довольно хорошо упорядочены и требуют мало перестановок.
В случае сортировки Шелла вычислительные затраты составляют N1,2.

Пирамидальная сортировка
Метод сортировки простым выбором основан на повторном выборе наименьшего ключа
среди n элементов, затем среди n-1 элементов, и т.д. Соответственно поиск наименьшего
элемента из n элементов потребует n-1 сравнений. Направление улучшения сортировки –
получать от каждого прохода больше информации, чем просто указание на один
наименьший элемент.
Пирамида это бинарное дерево (каждый узел которого имеет два дочерних узла)
высоты k, в котором:
1. все узлы имеют глубину k или k-1 - дерево сбалансированное;
2. при этом уровень k-1 полностью заполнен, а уровень k заполнен слева направо;
3. выполняется "свойство пирамиды": каждый дочерний элемент меньше, либо
равен родителю.
Как хранить пирамиду? Наименее хлопотно - поместить ее в массив. Соответствие между
геометрической структурой пирамиды как дерева и массивом устанавливается по
следующей схеме:
 в A[0] хранится корень дерева;

31
 левый и правый сыновья элемента A[i] хранятся, соответственно, в A[2i+1] и
A[2i+2].
Схема хранения проиллюстрирована на рисунке 9.2.
[0]

44
[1] [2]

55 12
[3] [4] [5] [6]

42 94 18 06
[7]

67

[44,55,12,42,94,18,06,67]
Рисунок 5.2.– Размещение пирамиды в массиве

Пирамидальная сортировка состоит из двух фаз:


1. Построение пирамиды (просеивание).
2. Фаза сортировки.
Начать построение пирамиды можно с A[k]...A[n], k = [size/2]. Эта часть массива
удовлетворяет свойству пирамиды, так как не существует индексов i, j: i = 2i+1 (или j =
2i+2) просто потому, что такие i, j находятся за границей массива. Другими словами
работа начинается с того узла, у которого имеется хотя бы один дочерний узел (см. рис.
5.3).
Далее будем расширять часть массива, обладающую столь полезным свойством,
добавляя по одному элементу за шаг. Следующий элемент на каждом шаге добавления -
тот, который стоит перед уже готовой частью.
Чтобы при добавлении элемента сохранялась пирамидальность, будем использовать
следующую процедуру расширения пирамиды A[i+1]..A[n] на элемент A[i] влево:
1. Смотрим на сыновей слева и справа - в массиве это A[2i+1] и A[2i+2] и выбираем
наибольшего из них.
2. Если этот элемент больше A[i] - меняем его с A[i] местами и идем к шагу 2, имея в
виду новое положение A[i] в массиве. Иначе конец процедуры.

32
1) 44 2) 44 3) 44

55 12 55 12 55 12

42 94 18 06 42 94 18 06 67 94 18 06

67 Исходная пирамида 67 42

44 44 94
4) 5) 6)
55 18 94 18 44 18

67 94 12 06 67 55 12 06 67 55 12 06

Самое большое значение на


42 42 42 вершине пирамиды

Рисунок 5.3. – Фаза просеивания элемента пирамиды

Итак, задача построения пирамиды из массива успешно решена. Как видно из свойств
пирамиды, в корне всегда находится максимальный элемент. Отсюда вытекает алго-
ритм фазы 2:
1. Берем верхний элемент пирамиды A[0]...A[n] (первый в массиве) и меняем с
последним местами (см. рис. 9.4). Теперь "забываем" об этом элементе и далее
рассматриваем массив A[0]...A[n-1]. Для превращения его в пирамиду достаточно
просеять лишь новый первый элемент.
2. Повторяем шаг 1, пока обрабатываемая часть массива не уменьшится до одного
элемента.

1) 94 2) 42

44 18 44 18

67 55 12 06 67 55 12 06

Самое большое значение опускаем


Значение 42 поднимается на место
42 вниз пирамиды и больше к нему не 94 94
обращаемся

Рисунок 5.4. – Фаза сортировки пирамиды

Очевидно, в конец массива каждый раз попадает максимальный элемент из текущей


пирамиды, поэтому в правой части постепенно возникает упорядоченная
последовательность.
Вычислительные затраты пирамидальной сортировки составляют N log( N ) .

33
Сортировка с разделением (быстрая сортировка)
Сортировка с разделением, хоть и была разработана более 40 лет назад К. Хоором,
является наиболее широко применяемым и одним их самых эффективных алгоритмов.
Сортировка основана на том принципе, что для достижения максимальной
эффективности следует производить обмены элементов на больших расстояниях.
Метод основан на подходе "разделяй и властвуй". Общая схема такова:
1. Из центральной части массива случайным образом выбираем какой-то элемент,
например X;
2. Двигаемся по массиву слева направо пока не находим элемент A[i]>X.
3. Двигаемся по массиву справа налево пока не находим элемент A[j]<X.
4. Элементы A[i] и A[j] меняем местами.
5. Вновь продолжаем процесс с обменом пока два просмотра не встретятся где-то в
центре массива.
В результате массив разделится на две части, причём в левой его части будут находиться
элементы меньшие X, а в правой – больше X (см. рис. 9.5).

Опорный элемент

44 55 12 42 94 18 06 67

06 18 12 42 94 55 44 67

<=42 >42
Рисунок 5.5. – Разделение массива

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


частям массива. Процесс продолжается до тех пор, пока каждая из частей не будет
состоять из одного единственного элемента.
При использовании алгоритма сортировки с разделением программисты стараются
корректно выбрать медианный элемент. Медианой массива называется элемент,
значение которого меньше (или равно) половины элементов массива и больше
другой половины массива.
Вычислительные затраты быстрой сортировки составляют N log( N ) .

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. – СПб.:
Невский Диалект, 2007. – 352 с.: ил.

34
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в Delphi.
Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.: Питер, 2006 – 557 с.
3. Дональд Э. Кнут. Искусство программирования. Том 1. Основные алгоритмы 3-е
издание — СПб.:Вильямс, 2011. — 720 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


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

1. Напишите три программы сортировки, используя изученные на данной лабораторной


работе улучшенные методы сортировки массива.

2. Предложите алгоритм поиска медианного элемента массива для сортировки с


разделением.

35
6. Работа с последовательностями, файлы

Практическое занятие – 6 часа

Цель занятия: исследование особенностей последовательного хранения данных и


операций ввода/вывода. Позволяет развить способность собрать и провести анализ исход-
ных данных для проектирования подсистем и средств обеспечения информационной без-
опасности (ПК - 18), способность использовать основные естественнонаучные законы,
применять математический аппарат в профессиональной деятельности, выявлять сущ-
ность проблем, возникающих в ходе профессиональной деятельности (ПК - 1) и способ-
ность использовать инструментальные средства и системы программирования для реше-
ния профессиональных задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуляция.
Вопросы, выносимые на обсуждение:
1. Что понимается под последовательным хранением данных?
2. Какие следствия последовательного доступа вам известны?
3. Как организовать доступ к файлу для чтения (для записи)?
4. Как предотвратить операцию чтения за пределами файла?
5. Какие основные и дополнительные операции над последовательным файлом
вам известны?

Методические рекомендации
Общее свойство структур данных, которые рассматривались на прошлом занятии, а
именно массива, записи и множества, заключается в том, что их кардинальное число
конечно. Это значительно упрощает процесс разработки программы.
Большинство так называемых усложненных структур: последовательности, деревья,
графы и т. д. – характеризуются тем, что их кардинальные числа бесконечны. Как
следствие:
1. Объем памяти, необходимый для размещения структуры усложненного типа,
неизвестен во время трансляции.
2. Объём памяти под данные может изменяться во время выполнения программы.
Если размер данных заранее неизвестен и может динамически изменяться в ходе
выполнения кода, то наиболее простым способом их размещения в памяти станет
последовательное хранение, будто бы это пачка листов бумаги в которую вы каждый раз
докладываете очередной лист.

Последовательность, хранящая данные одного типа, работающая на основе


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

Смысл последовательного доступа заключается в том, что в каждый момент доступна


лишь одна определённая компонента последовательности. Как следствие из этого:

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

x  x1 , x2 ,..., xn2 , xn1 , xn

Рисунок 6.1.– Изменение позиции последовательности

Доступ к файлу
С точки зрения программирования файлы можно классифицировать на:
1. Двоичные (бинарные).
2. Текстовые.
3. Типизированные.

Синтаксис объявления файла в языке Delphi выглядит следующим образом:


var F : File of <тип файла>;
Например:
var
Bin_File : file; //двоичный файл
Txt_File : Textfile; //текстовый файл
Int_File : file of Integer; //файл целых чисел
Real_File : file of Real; //файл вещественных чисел
Record_File : file of TPoint; //типизированный файл

Предлагаю вашему вниманию стандартный каркас исходного кода по работе с файлом,


на который рекомендуется опираться вне зависимости от типа файла.

var F : file;
begin
AssignFile(F,'C:\MyFile.dat'); //Связывание файловой переменной F с
файлом
TRY
//Секция для потенциально опасных операций над файлом
FINALLY
CloseFile(F); //Закрытие файла и освобождение переменной
END;
end.

37
Прокомментирую эти строки. Нами объявлена файловая переменная с именем F. Самая
первая процедура, встретившаяся в листинге, предназначена для связывания файловой
переменной F с именем файла FileName. Эту процедуру дальше станем называть
процедурой инициализации базовых операций ввода-вывода.
procedure AssignFile(var F; FileName: string);

Теперь файловая переменная в состоянии держать связь с эти файлом до тех пор, пока не
будет освобождена. Для разрыва связи и освобождения занятых ресурсов необходим
вызов процедуры закрытия файла.
procedure CloseFile(var F);

Указанный метод завершает операции ввода-вывода. Обе процедуры всегда


применяются в паре, и если в программе был осуществлён вызов AssignFile(), то в
заключении позаботьтесь и об обязательном вызове CloseFile(). Однако, при работе с
файлом всегда высока вероятность возникновения целого спектра самых разнообразных
ошибок, которые могут привести к возникновению исключительной ситуации. Именно
по этому в примере процедура закрытия вынесена в секцию finally обработчика ошибки
try..finally. Такой подход гарантирует, что даже при возникновении ошибок файловая
переменная гарантированно освобождается.

Операции над файлами

Все действия с последовательными файлами можно свести к 4-м операциям.

Первая операция создаёт пустую последовательность. Она реализуется с помощью


процедуры:
procedure Rewrite(var F: File [; RecSize: Word ] );

Будьте осторожны! Если файловая переменная F ссылается на файл с данными, то ука-


занный файл будет перезаписан и потеряет всю информацию!
Вторая операция увеличивает последовательность. Благодаря этому
последовательность получает приращение на одно значение. На основе данной операции
построен механизм записи данных в последовательный файл. Для текстовых файлов:
procedure Writeln([ var F: Text; ] V1 [, V2, ...,Vn ]);

Процедура добавит в файл F текстовую строку. Кроме того, для текстовых и


типизированных файлов допускается применять процедуру:
procedure Write( [var F: Text; ] P1 [ , P2,..., Pn] );

На этот раз процедура добавит в конец последовательности одно значение. Например,


если речь идёт о целочисленном файле, то добавится целое число. Для двоичных файлов
подойдёт процедура:
procedure BlockWrite (var f: File; var Buf; Count: Integer);

38
Второй аргумент Buf служит буфером, в который мы помещаем данные. Третий аргу-
мент Count указывает сколько байт из буфера следует передать в файл.
Третья операция применяется в случаях, когда мы планируем считать данные из файла,
она называется “инициация просмотра”. На практике для этого потребуются услуги
процедуры:
procedure Reset(var F: File; [RecSize: Word ] );

Четвёртая операция позволяет осуществлять переход к следующей компоненте файла.


В Delphi, для таких целей применяется процедура:
procedure Seek(var F; N: Longint);

Первый аргумент данного метода (как, впрочем, и всех других методов ввода-вывода)
требует передачи файловой переменной. Второй параметр определяет – в каком месте
файла мы собираемся оказаться.
На законный вопрос: “А как узнать в каком месте находится указатель в настоящий
момент?” нам ответит ещё одна функция:
function FilePos(var F): Longint;

К четвёртой операции с файлами прямое отношение имеет действие, связанное с чтени-


ем данных из файла, ведь каждая операция чтения тоже приводит к переходу к очеред-
ной компоненте последовательности.
Для чтения целой строки из текстового файла применяем процедуру:
procedure Readln([ var F: Text; ] V1 [, V2, ...,Vn ]);

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


procedure Read( [ var F: Text; ] V1 [, V2,...,Vn ] );

Она производит чтение порциями, по одному элементу.


Для двоичных файлов допускается применить операцию поблочного чтения:
procedure BlockRead (var F: File; var Buf; Count: Integer);

Параметры процедуры аналогичны параметрам, применяемым в рассмотренной выше


BlockWrite(), с той лишь разницей, что сейчас мы читаем данные из файла.

Окончание файла
При просмотре последовательности важно уметь распознавать её окончание, поскольку
операция чтения за пределами последовательности приводит к ошибке. Для этой цели
воспользуйтесь функцией:
function Eof(var F): Boolean;

В случае если достигнуто окончание файла, функция возвратит значение true, во всех
остальных случаях – false.

39
На законный вопрос: “А как узнать в каком месте находится указатель в настоящий
момент?” нам ответит ещё один метод:
function FilePos(var F): Longint;

И если указатель ссылается на начало файла, то функция вернёт нулевое значение, а если
на конец, то возвратится значение FileSize (). Этот метод проинформирует программиста
о количестве записей в типизированном файле:
function FileSize(var F): Integer;

Чтобы нам не выйти за пределы типизированного файла при его чтении стоит
использовать следующую заготовку кода:

while FilePos(F)<>FileSize(F) do
begin
Read(F, Буферная_Переменная);
//другие операции
end;

Пример работы с файлом

Рассмотрите два приёма работы с типизированным файлом. В первом листинге мы


создаём файл типизированный типом данных Integer и заполняем его 10 элементами.

program ...;
{$APPTYPE CONSOLE}
uses SysUtils;
var I : INTEGER; F : File Of INTEGER;
begin
AssignFile(F,'C:\int.dat'); {связывание файловой переменной с
именем файла}
Rewrite(F); //создание файла
TRY
For I:=1 to 10 do
Write(F,I); //внесение значений в файл
FINALLY
CloseFile(F); //закрытие файла
END;
end.

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

var I : INTEGER; F : File Of INTEGER;


begin
AssignFile(F,'C:\int.dat'); {связывание файловой переменной с
именем файла}
Reset(F); //подготовка файла к чтению
TRY
WHILE EOF(F)<>TRUE do //контролируем окончание файла
begin

40
Read(F,I); //внесение 10 значений в файл
WriteLn(I); //вывод на экран
End;
FINALLY
CloseFile(F); //закрытие файла
END;
ReadLn;
end.

Рекомендуемая литература
1. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. – СПб.:
Невский Диалект, 2007. – 352 с.: ил.
2. Осипов Д. Delphi XE2. СПб.: Издательство БХВ, – 2012. – 912 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


1. Разработайте процедуру, заполняющую файл “A” произвольным количеством
случайных вещественных чисел REAL в диапазоне от -100.0 до 100.0.
2. Разработайте процедуру выводящие на экран данные из произвольного файла,
типизированного типом данных REAL. Проверьте её работоспособность на файле
“A”.
3. Разработайте процедуру, декомпозирующую файл из первого задания следующем
образом: целая часть значений передаётся в файл “B”, дробная направляется в
файл “С”.
4. Разработайте процедуру, объединяющую целую и дробную части из файлов “B” и
“C” (см. задание 3) в файл “D”.
5. Разработайте процедуру, позволяющую вывести содержание файла “A” в
обратной последовательности и сохраните полученные данные в файл “E”.
6. Разработайте процедуру, позволяющую конвертировать файл “A” к
типизированному файлу следующего вида:
a. поле порядкового номера;
b. поле, хранящее признак отрицательного или положительного значения;
c. поле, содержащее исходное значение по модулю.
Сохраните результат в файле “F”.

Примечание: При выполнении заданий не следует пользоваться услугами массивов!

41
7. Нелинейные структуры данных

Практическое занятие – 6 часа

Цель занятия: исследование способов хранения в памяти нелинейных структур


данных. Позволяет развить способность собрать и провести анализ исходных данных для
проектирования подсистем и средств обеспечения информационной безопасности (ПК -
18), способность использовать основные естественнонаучные законы, применять матема-
тический аппарат в профессиональной деятельности, выявлять сущность проблем, возни-
кающих в ходе профессиональной деятельности (ПК - 1) и способность использовать ин-
струментальные средства и системы программирования для решения профессиональных
задач (ПК - 16)
Организационная форма проведения занятия: компьютерная симуляция.
Вопросы, выносимые на обсуждение:
1. Что понимается под графом?
2. Как можно классифицировать графы?
3. Какие способы хранения графов в памяти вам известны (преимущества и не-
достатки)?
4. Как предотвратить операцию чтения за пределами файла?
5. Какие основные и дополнительные операции над последовательным файлом
вам известны?

Методические рекомендации
На данной лабораторной работе мы познакомимся с особенностями представления в
памяти двух базовых нелинейных структур данных: графа и бинарного дерева.

Граф
Самым привычным примером графа служит карта автодорог, на которой изображены
перекрестки и связывающие их дороги. Перекрестки являются вершинами графа, а
дороги - его ребрами. Иногда наши графы ориентированы (подобно улицам с
односторонним движением) или взвешены - каждой дороге приписана стоимость
путешествия по ней (если, например, дороги платные).

Граф - это сложная нелинейная многосвязная динамическая структура,


отображающая свойства и связи сложного объекта.

Как многосвязная структура граф обладает следующими свойствами:


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

42
2. в виде списка примыканий (смежностей).
Матрица примыканий AdjMat графа G = (V, E) с числом вершин записывается в виде
двумерного массива размером N х N. В каждой ячейке [i,j] этого массива записано
значение 0 за исключением лишь тех случаев, когда из вершины Vi в вершину Vj ведет
ребро, и тогда в ячейке записано значение 1.

1, если vi v j  E
AdjMat i, j    (13.1).
 0, если vi v j  E

Ячейка матрицы примыканий взвешенного графа или орграфа содержит бесконечность,


если соответствующее ребро отсутствует, а во всех остальных случаях ее значение равно
весу ребра. Диагональные элементы такой матрицы равны 0, поскольку путешествие из
вершины в нее саму не стоит ничего (см. рис. 13.1).

Неориентированный граф
(A) (B) (C) (D)

A B (A) 0 1 0 1

(B) 1 0 1 1

(C) 0 1 0 1
D C
(D) 1 1 1 0

Ориентированный граф
(A) (B) (C) (D)
A B
(A) 0 1 0 0

(B) 0 0 1 1

D C (C) 0 0 0 1

(D) 1 0 1 0

Рисунок 7.1. – Представление графа в виде матрицы примыканий

Список примыканий AdjList графа G = (V,E) с числом вершин V  N записывается в


виде одномерного массива длины N, каждый элемент которого представляет собой
ссылку на список (см. рис. 13.2).

A B C

B B A C D
A

C C A B E

D E D B E

E C D

Рисунок 7.2. – Представление графа в виде списка примыканий

43
Бинарное дерево
Дерево – это граф, который характеризуется следующими свойствами:
1. Существует единственный элемент (узел или вершина), на который не ссылается
никакой другой элемент и который называется “корнем”.
2. Начиная с корня и следуя по определенной цепочке указателей, содержащихся в
элементах, можно осуществить доступ к любому элементу структуры.
3. На каждый элемент, кроме корня, имеется единственная ссылка, т.е. каждый
элемент адресуется единственным указателем.
Наиболее простой разновидностью деревьев являются бинарные деревья. Это такие
деревья, у каждой вершины которых, имеется от 0 до 2 дочерних вершин.
В памяти ЭВМ деревья можно представлять с помощью связных списков и массивов
(или последовательных списков). Чаще всего используется связное представление
деревьев, т.к. оно очень сильно напоминает логическое. Связное хранение состоит в том,
что задается связь от родительской вершины к дочерней. У каждого элемента бинарного
дерева имеется два указателя, поэтому удобно узел представить в виде трёхэлементной
структуры (см. рис. 13.3).

Указатель на Указатель на
левое правое
поддерево поддерево

Рисунок 7.3. – Структура элемента бинарного дерева

Рекомендуемая литература
1. Седжвик. Р. Фундаментальные алгоритмы на C++. Анализ/Структуры
данных/Сортировка/Поиск: Пер. с англ./Роберт Седжвик. - К.: Издательство
«ДиаСофт», 2014.- 688 с.
2. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в Delphi.
Библиотека программиста. – М.: ООО “ДиаСофтЮП”: СПб.: Питер, 2016 – 557 с.
3. Дональд Э. Кнут. Искусство программирования. Том 1. Основные алгоритмы 3-е
издание — СПб.:Вильямс, 2015. — 720 с.
Интернет-ресурсы
Материалы сайта http://algolist.manual.ru.

Задания для развития и контроля владения компетенциями


1. Разработайте программу позволяющую хранить информацию об ориентированном
графе произвольного размера. Программа должна содержать процедуры:
1. Добавления вершины в граф.

44
2. Удаления вершины из графа.
3. Вывода информации о составе графа.
4. Сохранения (чтения) данных в файл.
Программа должна позволять пользователю выбирать формат хранения данных
(матрица примыканий или список примыканий).
2. Разработайте программу позволяющую хранить информацию об иерархической
структуре в формате бинарного дерева. Программа должна содержать процедуры:
1. Добавления вершины в произвольное место дерева.
2. Удаления вершины (и всех дочерних элементов) из дерева.
3. Вывода информации о составе дерева.
4. Сохранения (чтения) данных в файл.

Примечание: разработанная на данном занятии программа (хранящая информацию


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

Примечание: при выполнении первого задания вам может помочь компонент


TStringGrid.

45
Литература
1. Технология программирования: учебник/ Г.С. Иванова. — М.:КНОРУС, 2015. —
336 с.
2. Скиена С. Алгоритмы. Руководство по разработке. — 2-е изд.: Пер. с англ. — СПб.:
БХВ-Петербург, 2011. — 720 с.: ил.
3. Технологии объектно-ориентированного программирования: учебник/ Хорев П.Б.
— М.:Academia, 2008 — 448c.
4. Дональд Э. Кнут. Искусство программирования. Том 1. Основные алгоритмы 3-е
издание — СПб.:Вильямс, 2011. — 720 с.
5. Дональд Э. Кнут. Искусство программирования, Том 2. Получисленные алгоритмы
3-е издание— СПб.:Вильямс, 2011. — 832 с.
6. Кормен. Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ.—М.; МЦН-
МО, 2006, 960 с.
7. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр. – СПб.:
Невский Диалект, 2007. – 352 с.: ил.
8. Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в Delphi. Библиоте-
ка программиста. – М.: ООО “ДиаСофтЮП”: СПб.: Питер, 2006 – 557 с.
9. Осипов Д. Delphi. Профессиональное программирование. Профессиональное про-
граммирование. – СПб.: Символ-Плюс, 2006. – 1056 с.: ил.
10. Осипов Д. Графика в проектах Delphi. – СПб.: Символ-Плюс, 2008. – 648 с.: цв. ил.
11. Осипов Д. Delphi XE2. СПб.: Издательство БХВ, – 2012. – 912 с.
12. Луиза Тамре. Введение в тестирование программного обеспечения. – М., Вильямс,
2003, 368 с.

46
Федеральное государственное автономное образовательное учреждение высшего
образования
Северо-Кавказский федеральный университет
Институт информационных технологий и телекоммуникаций

МЕТОДИЧЕСКИЕ РЕКОМЕНДАЦИИ ДЛЯ СТУДЕНТОВ


ПО ОРГАНИЗАЦИИ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
по дисциплине «Технологии и методы программирования»
для бакалавров направления 10.03.01 «Информационная безопасность»

Ставрополь 2017 г.
СОДЕРЖАНИЕ
Введение ....................................................................................................................... 3
1. Общая характеристика самостоятельной работы студента ................................ 4
2. Технологическая карта самостоятельной работы студента ...................................... 6
3. Самостоятельное изучение тем лекций ................................................................ 6
4. Паспорт фонда оценочных средств для проверки самостоятельной работы .... 6
5. Список рекомендуемой литературы.................................................................... 20
Введение
Целью изучения дисциплины «Технологии и методы программирования»
являетсяформирование набора общекультурных и профессиональных компе-
тенций будущего специалиста по направлению подготовки 10.03.01 «Информа-
ционная безопасность».
Задачами дисциплины являются:
1. Формирование четких представлений о современных технологиях и
методах программирования;
2. Обучение основам построения алгоритмов сортировки, поиска, алго-
ритмов на графах, генерации случайных последовательностей, генерации под-
становок, структур данных;
3. Развитие навыков проектирования и оценки качества программного
обеспечения, инновационного подхода к вопросам разработки и сопровождения
программного обеспечения.
Компетенции обучающегося, формируемые в результате освоения дисци-
плины:
Индекс Формулировка:
ПК-2 способностью применять программные средства си-
стемного, прикладного и специального назначения, ин-
струментальные средства, языки и системы программи-
рования для решения профессиональных задач
ОПК-4 способностью понимать значение информации в разви-
тии современного общества, применять информацион-
ные технологии для поиска и обработки информации

В результате освоения дисциплины обучающийся должен:

Технологии фор- Средства и тех-


Перечень компонентов мирования ком- нологии оценки
петенции
Знать:
- место и роль информационной лекции, собеседование,
безопасности в системе националь- самостоятельная письменный от-
ной безопасности Российской Фе- работа чет
дерации;
- способы оценки качества про-
граммного обеспечения;
- современные средства разработки
и анализа программного обеспече-
ния на языках высокого уровня;
3
- основы объектно-
ориентированного проектирования;
жизненный цикл программного
продукта;
- порядок тестирования, докумен-
тирования и сопровождения про-
граммного продукта.

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

1. Общая характеристика самостоятельной работы студента

Основными видами учебной работы по достижению результатов освое-


ния дисциплины являются лекции, лабораторные и практические работы и са-
мостоятельная работа студентов (СРС).
На лекциях раскрываются основные положения и понятия курса, форми-
руются знания в области технологии и методов программирования. На лабора-
торных и практических работах формируются умения и навыки, необходимые
для решения задач профессиональной деятельности.
Приступая к изучению учебной дисциплины, необходимо ознакомиться с
учебной программой, получить в библиотеке рекомендованные учебные посо-
бия, а также получить у ведущего преподавателя в электронном виде конспекты
лекций, методические рекомендации к лабораторным и практическим работам
и тестовые, завести новую тетрадь для конспектирования лекций и выполнения
лабораторных и практических работ.
Для изучения дисциплины предлагается список основной и дополнитель-
ной литературы. Основная литература предназначена для обязательного изуче-
ния, дополнительная – поможет более глубоко освоить отдельные вопросы,
4
подготовить исследовательские задания и выполнить задания для самостоя-
тельной работы.
В ходе лекционных занятий студент обязан осуществлять конспектирова-
ние учебного материала, особое внимание, обращая на категории, формулиров-
ки, раскрывающие содержание тех или иных понятий, физических явлений,
процессов, эффектов. В рабочих конспектах желательно оставлять поля, на ко-
торых следует делать пометки из рекомендованной литературы, дополнять ма-
териал прослушанной лекции, формулировать научные выводы и практические
рекомендации. Студент имеет право задавать преподавателю уточняющие во-
просы с целью уяснения теоретических положений, разрешения спорных ситу-
аций.
Самостоятельная работа студентов над материалом учебной дисциплины
является неотъемлемой частью учебного процесса и должна предполагать
углубление знания учебного материала, излагаемого на аудиторных занятиях, и
приобретение дополнительных знаний по отдельным вопросам самостоятельно.
Основными видами самостоятельной работы курсантов по учебной дис-
циплине являются:
 самостоятельное изучение учебного материала по заданным темам;
 подготовка к лабораторным работам, оформление отчета по выпол-
ненному практическому занятию и подготовка к собеседованию по результа-
там работы.
Основными методами самостоятельной работы студентов являются:
1) для овладения знаниями:
 чтение текста (конспекта лекций, учебника, дополнительной литера-
туры) и конспектирование текста;
 работа с нормативными документами;
 поиск информации в Интернет;
2) для закрепления и систематизации знаний:
 работа с конспектом лекции (обработка текста);
 повторная работа над учебным материалом (учебника, дополнитель-
ной литературы, слайдами);
 составление плана и тезисов ответа или графическое изображение
структуры ответа;
 составление таблиц для систематизации учебного материала;
 изучение нормативных документов;
 ответы на контрольные вопросы;
3) для формирования умений:
 подготовка к практическим и лабораторным занятиям;
 решение задач и практических заданий;
 подготовка отчетов по практическим и лабораторным занятиям;
 рефлексивный анализ профессиональных умений.
В случае пропуска учебного занятия студент может воспользоваться со-
держанием различных блоков учебно-методического комплекса (лекции, прак-
5
тические и лабораторные занятия, контрольные вопросы и тесты) для самопод-
готовки и освоения темы. Для самоконтроля необходимо использовать вопросы
и задания, предлагаемые к практическим и лабораторным занятиям, а также ва-
рианты тестовых заданий.

2. Технологическая карта самостоятельной работы студента

Код ре- Итоговый про- Средства и Обьем


ализуе- дукт самостоя- технологии часов
Вид деятельности сту-
мой тельной работы оценки
дентов
компе-
тенции
1 семестр
ОПК-4 Подготовка к лабора- Письменный Собеседова- 8
ПК-2 торным занятиям 1, 4, отчет ние
5

ОПК-4 Самостоятельное изу- Конспект Собеседова- 4


ПК-2 чение темы № 5 ние
ОПК-4 Самостоятельное ре- Письменный Собеседова- 12
ПК-2 шение разноуровне- отчет с реше- ние
вых задач по темам № нием разно-
2,4, 5,7 уровневых за-
дач
ОПК-4 Самостоятельное изу- Создание пре- Собеседова- 4
ПК-2 чение программного зентации ние
продукта Delphi
Итого за 4 семестр 28

3. Самостоятельное изучение тем лекций


№ Рекомендуемые источники ин-
п/п Темы для самостоятельного формации
изучения (№ источника)
Основ- Допол- Мето- Интер-
ная ни- диче- нет-
тельная ская ресурсы
1 семестр
1 Технология программирования 1 1, 2, 4, 5 3
2 Искусство программирования, 3 3, 4, 5 1,2

4. Паспорт фонда оценочных средств для проверки самостоятельной


работы
6
Код оце- Модуль, Тип Вид Компонент Количество
ниваемой раздел, кон- кон- фонда оце- заданий для каж-
компетен- тема троля троля ночных дого уровня, шт.
ции (или (в соответ- средств Базовый Повы-
её части) ствии с шен-
Програм- ный
мой)
4 семестр
ОПК-4 9, 10, 11, текущий устный Вопросы 99 11
ПК-2 14 для собесе-
дования по
лаборатор-
ным рабо-
там
ОПК-4 3, 4, 5 текущий устный Вопросы 99 11
ПК-2 для собесе-
дования по
самостоя-
тельному
изучению
тем дисци-
плины
ОПК-4 12 текущий устный Вопросы 99 11
ПК-2 для собесе-
дования по
самостоя-
тельному
изучению
программ-
ного про-
дукта Del-
phi
Проме- устный Вопросы к 110
жуточ- экзаменам
ный (эк-
замен)

4.1 Вопросы для проверки уровня обученности

7
Базовый уровень:
Знать:

1. Что такое технология программирования (ТП)?Какие основные этапы


развития ТП вам известны?
2. Опишите проблемы разработки сложных программных систем.
3. Что включает блочно-иерархический подход к созданию сложных
систем?
4. Опишите жизненный цикл и этапы разработки программного
обеспечения.
5. Что понимается под эволюцией моделей жизненного цикла
программного обеспечения.
6. Как осуществляется ускорение разработки программного
обеспечения(технология RAD)?
7. Как оценивается качество процессов создания программного
обеспечения?
8. Раскройте понятие технологичности программного обеспечения.
9. Раскройте понятие программных модулей и их свойств.
10. Что такое нисходящая и восходящая разработка программного
обеспечения?
11. Какие средства описания структурных алгоритмов вам известны?
12. Что такое стиль оформления программы?
13. Чем определяется эффективность и технологичность ПО?
14. Что понимается под программированием «с защитой от ошибок»?
15. Как производится сквозной структурный контроль?
16. Как классифицируются программные продукты по функциональному
признаку?
17. Какие основные эксплуатационные требования к программным
продуктам вам известны?
18. Что входит в предпроектные исследования предметной области?
19. Как осуществляется разработка технического задания?
20. Какие принципиальные решения начальных этапов проектирования
вам известны?
21. Спецификации программного обеспечения при структурном подходе.
22. Как строятся диаграммы переходов состояний?
23. Как строятся функциональные диаграммы?
24. Как строятся диаграммы потоков данных?
25. Структуры данных и диаграммы отношений компонентов данных.
26. Математические модели задач, разработка или выбор методов
решения.
27. Как осуществляется разработка структурной и функциональной схем?
28. Раскройте порядок использование метода пошаговой детализации для
проектирования структуры программного обеспечения.
29. Что представляют собой структурные карты Константайна?

8
30. Что входит в проектирование структур данных?
31. Как производится проектирование программного обеспечения,
основанное на декомпозиции данных?
32. Case-технологии, основанные на структурных методологиях анализа и
проектирования.
33. Что такое UML?Как применяется UML при описании разработки
программных продуктов с использованием объектного подхода?
34. Как осуществляется построение концептуальной модели предметной
области?
35. Как осуществляется описание поведения? Системные события и
операции.
36. Как производится разработка структуры программного обеспечения
при объектном подходе?
37. Как определяются отношения между объектами?
38. Что понимается под уточнением отношений классов?
39. Как производится компоновка программных компонентов?
40. Как производится проектирование размещения программных
компонентов для распределенных программных систем?
41. Раскройте особенности спиральной модели разработки.
42. Как осуществляется реорганизация проекта?
43. Опишите типы пользовательских интерфейсов и этапы их разработки.
44. Раскройте психофизические особенности человека, связанные с
восприятием, запоминанием и обработкой информации.
45. Что такое пользовательская и программная модели интерфейса?
46. Произведите классификацию диалогов и раскройте общие принципы
их разработки.
47. Основные компоненты графических пользовательских интерфейсов.
48. Реализация диалогов в графическом пользовательском интерфейсе.
49. Пользовательские интерфейсы прямого манипулирования и их
проектирование.
50. Интеллектуальные элементы пользовательских интерфейсов.
51. Как осуществляется разработка технического задания?
52. Как производится анализ предметной области, уточнение
спецификаций и разработка структурной схемы?
53. Раскройте особенности проектирования интерфейса пользователя.
54. Как следует проектировать классы приложения?
55. Какие виды контроля качества разрабатываемого программного
обеспечения вам известны?
56. Как производится ручной контроль программного обеспечения?
57. Что такое структурное тестирование?
58. Что такое функциональное тестирование?
59. Как осуществляется тестирование модулей и комплексное
тестирование?
60. Что такое оценочное тестирование?

9
61. Классификация ошибок.
62. Методы отладки программного обеспечения.
63. Методы и средства получения дополнительной информации.
64. Общая методика отладки программного обеспечения.
65. Виды программных документов.
66. Что входит в состав пояснительной записки?
67. Что входит в состав руководство пользователя?
68. Какие основные правила оформления текстовых документов вам
известны?
69. Понятие типа данных. Концепция типов данных
70. Общая характеристика простых типов данных.
71. Структуры, представление в памяти.
72. Статические и динамические типы данных.
73. Стеки, очереди и деки.
74. Связные списки.
75. Понятие последовательности.
76. Операции над файлами.
77. Алгоритм работы с текстовым файлом.
78. Алгоритм работы с типизированным файлом.
79. Эмпирический анализ алгоритмов.
80. Математический анализ алгоритмов, O-нотация, задачи и способы
описания.
81. Постановка задачи сортировки, оценка алгоритмов сортировки.
82. Сортировка простыми включениями, алгоритм и оценка.
83. Сортировка бинарными включениями, алгоритм и оценка.
84. Сортировка простым выбором, алгоритм и оценка.
85. Сортировка простым обменом, алгоритм и оценка.
86. Шейкер сортировка, алгоритм и оценка.
87. Сортировка Шелла, алгоритм и оценка.
88. Метод сортировки с помощью дерева, достоинства и недостатки.
89. Пирамидальная сортировка, алгоритм и оценка.
90. Абстрактное обменное слияние файлов.
91. Сортировка файлов простым слиянием.
92. Сортировка файлов естественным слиянием.
93. Сортировка файлов сбалансированным многопутевым слиянием.
94. Поиск подстроки в строке, алгоритм Бойера-Мура.
95. Генераторы ПСП, линейный конгруэнтный метод и метод Фиббоначи.
96. Оценка качества генератора ПСП.
97. Применение критерия ХИ-квадрат при оценке ПСП.
98. Алгоритмы архивации. Метод Running.
99. Алгоритмы архивации. Метод LZW.
Уметь, Владеть:
Задачи для проверки умений и навыков

10
1. Разработайте две процедуры поиска наибольшего общего делителя
(НОД) произвольных чисел A и B. Первая процедура должна применять “лобо-
вой” поиск (обычный перебор). Вторая процедура может использовать любой
известный вам алгоритм поиска НОД, например алгоритм Евклида.
2. Разработайте структуру данных позволяющую составлять прайс-лист
магазина. В прайс-лист входят следующие позиции: название товара, цена за
единицу, единица измерения, количество.
3. Предложите структуру для хранения информации о произвольной му-
зыкальной мелодии. Помимо тона звуков, ваша структура должна уметь описы-
вать длительность звучания каждой ноты.

Повышенный уровень:

Знать:

1. Алгоритмы архивации. Кодирование Хаффмана.


2. Таблицы с прямой адресацией. Недостатки по сравнению с хеш-
таблицами.
3. Назначение хеширования, хеш-функции, требования к хеш-функциям.
4. Хеширование, причины возникновения коллизий и порядок борьбы с
ними.
5. Графы. Основные понятия теории графов.
6. Графы. Структуры данных для представления графов.
7. Деревья. Структуры данных для представления деревьев. Порядок пе-
ревода данных к бинарному дереву.
8. Графы. Алгоритмы обхода в глубину и по уровням.
9. Графы. Алгоритм поиска минимального основного дерева.
10. Графы. Алгоритм поиска кратчайшего пути.
11. Алгоритмы сравнения с образцом, алгоритмы сравнения строк

Уметь, Владеть:
Задачи для проверки умений и навыков
1. Разработайте программу, позволяющую хранить целочисленные дан-
ные в формате односвязного списка. Программа должна позволять пользовате-
лю:
 Создавать список.
 Добавлять элемент в конец списка.
 Вставлять элемент в произвольное место списка.
 Удалять любой элемент из списка.
 Читать данные из списка.
 Уничтожать весь список.
2. Разработайте программу, позволяющую хранить целочисленные дан-
ные в формате двусвязного списка. Реализуйте в вашей программе те же функ-
ции, что и в первом задании.
11
3. Напишите три программы сортировки, используя изученные на данной
лабораторной работе улучшенные методы сортировки массива.

4.2 Вопросы для собеседования по самостоятельному изучению дис-


циплины
По дисциплине Технология и методы программирования

1. Технология программирования
2. Искусство программирования

4.3 Комплект разноуровневых задач и заданий

по дисциплине Технология и методы программирования

1. Тема 5. Методы анализа алгоритмов


Типовые задачи (всего 11 заданий):
Задания базового уровня:
1) Разработайте блок-схему алгоритма сравнения 3 чисел и осуществите его
математическую оценку.
2) Разработайте блок-схему алгоритма решения квадратного уравнения и
осуществите его математическую оценку.
3) Разработайте блок-схему алгоритма поиска подстроки в текстовой стро-
ке и осуществите его математическую оценку.
4) Разработайте блок-схему алгоритма инвертирования двумерного массива
относительно его главной диагонали и осуществите его математическую оценку.
5) Разработайте блок-схему алгоритма инвертирования одномерного мас-
сива и осуществите его математическую оценку.
6) Разработайте блок-схему алгоритма поиска нечётных значений и осуще-
ствите его математическую оценку.
7) Разработайте блок-схему алгоритма суммирования значений двухмерно-
го массива ниже главной диагонали и осуществите его математическую оценку.
8) Разработайте блок-схему алгоритма суммирования значений двухмерно-
го массива выше главной диагонали и осуществите его математическую оценку.
Задания повышенного уровня:
9) Разработать на языке программирования C++ алгоритм поиска наиболь-
шего общего делителя и осуществите его математическую оценку.
10)Разработать на языке программирования C# алгоритм генерации после-
довательности чисел Фибоначчи и осуществите его математическую оценку.
11)Разработать на языке программирования Delphi алгоритм вычисления
факториала числа и осуществите его математическую оценку.
2. Тема 6. Фундаментальные структуры данных.
Типовые задачи (всего 9 заданий):
Задания базового уровня:

12
12)Смоделировать и исследовать в IDE Visual Studio структуру данных
предназначенную для хранения сведений о студенте.
13)Смоделировать и исследовать в IDE Delphi структуру данных предназна-
ченную для хранения сведений о студенте.
14)Смоделировать и исследовать в IDE Delphi структуру данных предназна-
ченную для хранения сведений о товаре в прайс–листе.
15)Смоделировать и исследовать в IDE Delphi структуру данных предназна-
ченную для хранения химической формулы.
16)Смоделировать и исследовать в IDE Visual Studio структуру данных
предназначенную для хранения математического выражения.
Задания повышенного уровня:
17)Смоделировать и исследовать в IDE Visual Studio структуру, позволяю-
щую хранить музыкальную мелодию.
18)Смоделировать и исследовать в IDE Delphi структуру, позволяющую
хранить изображение в векторном формате.
19)Смоделировать и исследовать в IDE Visual Studio структуру, позволяю-
щую хранить растровое изображение.
20)Смоделировать и исследовать в IDE Delphi структуру, позволяющую
хранить оцифрованный человеческий голос.
21) 3. Тема 8. Моделирование и исследование операций сортировки
данных в массивах.
Типовые задачи (всего 13 заданий):
Задания базового уровня:
22)Разработать алгоритм сортировки простым обменом и осуществить эм-
пирический анализ.
23)Разработать алгоритм сортировки простым обменом и осуществить эм-
пирический анализ.
24)Разработать и осуществить эмпирический анализ алгоритма шейкер-
сортировки.
25)Разработать и осуществить эмпирический анализ алгоритма сортировки
простым выбором.
26)Разработать и осуществить эмпирический анализ алгоритма сортировки
простыми вставками.
27)Разработать и осуществить эмпирический анализ алгоритма бинарной
сортировки.
28)Разработать и осуществить эмпирический анализ алгоритма сортировки
Шелла.
29)Разработать и осуществить эмпирический анализ алгоритма пирами-
дальной сортировки.
30)Разработать алгоритм быстрой сортировки и осуществить эмпирический
анализ.
31)Разработать и осуществить эмпирический анализ алгоритма естествен-
ной сортировки последовательного файла.
Задания повышенного уровня:

13
32)Разработать алгоритм быстрой сортировки двумерного массива и осуще-
ствить математический анализ.
33)Разработать алгоритм пирамидальной сортировки двумерного массива и
осуществить математический анализ.
34)Разработать алгоритм сортировки Шелла для двумерного массива и
осуществить его математический анализ.
4. Тема 14. Алгоритмы на графах.
Типовые задачи (всего 7 заданий):
Задания базового уровня:
35)Разработать приложение позволяющее хранить сведения о графе в виде
списка примыканий.
36) Разработать приложение позволяющее хранить сведения о графе в виде
матрицы смежности.
37)Разработать и осуществить анализ алгоритма (Дейкстры–Прима) постро-
ения минимального остовнго дерева.
38)Разработать алгоритм обхода графа в глубину.
39)Разработать алгоритм обхода графа по уровням.
Задания повышенного уровня:
40)Разработать и исследовать алгоритм поиска кратчайшего пути в графе.
41)Разработать и исследовать алгоритм поиска компонент двусвязности в в
графе.
5. Тема 17. Генераторы псевдослучайных последовательностей.
Типовые задачи (всего 10 заданий):
Задания базового уровня:
42)Смоделировать в среде Mathcad и исследовать в линейный конгруэнтный
генератор ПСП.
43)Смоделировать в среде Mathcad и оценить равномерность распределения
случайных чисел у генератора ПСП.
44)Смоделировать в среде Mathcad и оценить замкнутость цикла получения
случайных чисел у генератора ПСП..
45)Смоделировать в среде Mathcad и осуществить тест на пропуски у по-
следовательности случайных чисел.
46)Смоделировать в среде Mathcad и осуществить тест на длительность пе-
риода повторения у последовательности случайных чисел
Задания повышенного уровня:
47)Разработать на языке программирования C++ и исследовать в линейный
конгруэнтный генератор ПСП.
48)Разработать на языке программирования C# и исследовать в линейный
конгруэнтный генератор ПСП.
49)Разработать на языке программирования Delphi и исследовать в линей-
ный конгруэнтный генератор ПСП.
50)Разработать в программной среде C++ функцию тестирования ПСП на
пропуски.

14
51)Разработать в программной среде Delphi функцию тестирования ПСП
на равномерность распределения случайных чисел.
52)Разработать в программной среде C# функцию тестирования ПСП на
замкнутость цикла.

4.4 Вопросы для собеседования по самостоятельному изучению про-


граммного продукта Delphi

1. Имеют ли файлы проектов C++Builder и Delphi одинаковые расшире-


ния?
2. Имеют ли файлы форм C++Builder и Delphi одинаковые расширения?
3. Можно ли использовать пакеты от независимых производителей ком-
понентов как в C++Builder, так и в Delphi?
4. Можно ли открыть файл формы Delphi в C++Builder?
5. Можно ли редактировать файл формы Delphi в конструкторе форм
C++Builder?
6. Можно ли использовать в Delphi исходный модуль C++Builder?
7. Что лучше, C++Builder или Delphi?
4.5 Вопросы для собеседования по лабораторным работам
Лабораторная работа 1. Жизненный цикл и этапы разработки ПО
Базовый уровень:

1. Что такое жизненный цикл ПО?


2. Что такое процесс разработки ПО?
3. Какие модели жизненного цикла ПО вам известны?
Повышенный уровень:
1. Что такое CASE-технология?

Лабораторная работа 2. Технологичность программного обеспечения


Цель
Базовый уровень:
1. Что понимается под технологичностью программного продукта?
2. Что такое программный модуль?
3. Какие основные методы повышения технологичности ПО вам извест-
ны?
4. Что понимается под сцеплением модулей и какие виды сцепления вам
известны?

Повышенный уровень:

1. Что понимается под связностью модулей и какие виды связности вам


известны?

Лабораторная работа 3. Спецификации приструктурномподходе


15
Базовый уровень:
1. Что такое спецификация разрабатываемого ПО?
2. Роль диаграмм переходов в разработке ПО?
3. Что представляет собой функциональные диаграммы?
4. При решении каких задач следует применять диаграммы потоков
данных?
Повышенный уровень:
1. Что такое структурный подход при разработке ПО?

Лабораторная работа 4. Проектирование ПО при структурном подхо-


де
Базовый уровень:
1. Для чего предназначена структурная схема ПО?
2. Что должно быть описано в функциональной схеме ПО?

Повышенный уровень:
1. Что такое “пошаговая детализация”?

Лабораторная работа 5. Методы анализа алгоритмов


Базовый уровень:
1. Что такое алгоритм?
2. Какие качества должны быть у алгоритма?
3. Какие основные методы оценки качества алгоритмов вам известны?
4. Что такое основной параметр алгоритма?
Повышенный уровень:
1. Какие функции оценки производительности алгоритма вам известны?

Лабораторная работа 6. Фундаментальные структуры данных


Базовый уровень:
1. Что понимается под типом данных?
5. Как классифицируется типы данных?
6. Какие особенности работы со структурными типами данных вам из-
вестны?
Повышенный уровень:
1. Как представлены в памяти массивы и записи?

Лабораторная работа 7. Динамические структуры данных, связные


списки
Базовый уровень:
1. Что такое указатель?
2. Какой объём памяти отводится для хранения указателя?
3. Для чего необходима структура данных “список”?
4. Что понимается под связным списком?

16
Повышенный уровень:
1. Какие разновидности связных списков вам известны?

Лабораторная работа 8. Простейшие методы сортировки массивов


Базовый уровень:
1. Что такое указатель?
2. Какой объём памяти отводится для хранения указателя?
3. Для чего необходима структура данных “список”?
4. Что понимается под связным списком?
Повышенный уровень:
1. Какие разновидности связных списков вам известны?

Лабораторная работа 9. Улучшенные методы сортировки массивов


Базовый уровень:
8. В чём заключается принципиальное отличие простейших и улучшен-
ных методов сортировки массивов?
9. Как оценивается эффективность алгоритма сортировки?
Повышенный уровень:
1. Что понимается под медианным элементом в алгоритме быстрой сор-
тировки?

Лабораторная работа 10. Алгоритмы поиска данных по образцу


Базовый уровень:
1. Где на практике следует применять алгоритмы поиска данных?
2. Какой основной недостаток алгоритма прямого поиска?
Повышенный уровень:
1. Как надо модифицировать алгоритм Бойера-Мура для поиска текста в
коди-ровке Unicode?

Лабораторная работа 11. Работа с последовательностями, файлы


Базовый уровень:
1. Что понимается под последовательным хранением данных?
2. Какие следствия последовательного доступа вам известны?
3. Как организовать доступ к файлу для чтения (для записи)?
4. Как предотвратить операцию чтения за пределами файла?
Повышенный уровень:
1. Какие основные и дополнительные операции над последовательным
файлом вам известны?

Лабораторная работа 12. Упорядочивание файловых последователь-


ностей
Базовый уровень:

1. Что понимается под последовательным хранением данных?

17
2. Какие следствия последовательного доступа вам известны?
3. Как организовать доступ к файлу для чтения (для записи)?
4. Как предотвратить операцию чтения за пределами файла?
Повышенный уровень:
1. Какие основные и дополнительные операции над последовательным
файлом вам известны?

Лабораторная работа 13. Нелинейные структуры данных


Базовый уровень:
1. Что понимается под графом?
2. Как можно классифицировать графы?
3. Какие способы хранения графов в памяти вам известны (преимущества
и не-достатки)?
4. Как предотвратить операцию чтения за пределами файла?
Повышенный уровень:
1. Какие основные и дополнительные операции над последовательным
файлом вам известны?

Лабораторная работа 14. Базовые алгоритмы на графах


Базовый уровень:
1. Какие алгоритмы используются для посещения всех узлов графа?
2. Что такое минимальное остовное дерево (МОД)?
3. Можно ли применять алгоритм МОД при поиске кратчайшего пути?
4. Что такое “жадный” алгоритм?
Повышенный уровень:
1. Какие способы поиска кратчайшего пути между двумя вершинами гра-
фа вам известны?
4.6 Вопросы для собеседования по практическим занятиям
Практическое занятие 1. Технологии программирования. Основные
понятия и подходы.
Базовый уровень:
1. Какие основные этапы развития технологии программирования
существуют?
2. Перечислить этапы разработки программного обеспечения (ПО).
Повышенный уровень:
3. Произвести оценку качества процессов создания ПО.

Практическое занятие 2. Приёмы обеспечения технологичности


программных продуктов
Базовый уровень:
4. Какие этапы эволюции моделей жизненного цикла программного
обеспечения существуют?
5. Какие модули сущесвуют? Их свойства.

18
Повышенный уровень:
6. Какие средства описания структурных алгоритмов существуют?

Практическое занятие 3. Определение требований к ПО и исходных


данных для его проектирования

Базовый уровень:
7. Классификация программных продуктов по функциональному
признаку.
8. Основные эксплуатационные требования к программным
продуктам.

Повышенный уровень:
9. Решение задач.

Практическое занятие 4. Алгоритмы поиска (сравнения с образцом)

Базовый уровень:
10. Представление графов в памяти
11. Алгоритмы на графах

Повышенный уровень:
12. Решение задач.

Практическое занятие 5. Методы сжатия данных

Базовый уровень:
13. Метод Running
14. Идея арифметического кодирования
15. Словарные методы сжатия, алгоритм LZW
16. Алгоритм Хаффмана

Повышенный уровень:
17. Решение задач.

Практическое занятие 6. Хеширование

Базовый уровень:
18. Таблицы с прямой адресацией
19. Хеш-таблицы
20. Хеш-функции

Повышенный уровень:
21. Решение задач.

19
Практическое занятие 7. Графические алгоритмы

Базовый уровень:
22. Представление цвета
23. Алгоритмы черчения графических примитивов
24. Алгоритмы закраски замкнутых областей

Повышенный уровень:
25. Решение задач.

5. Список рекомендуемой литературы

5.1. Основная литература


1. Технология программирования: учебник/ Г.С. Иванова. –
М.:КНОРУС, 2013. – 336 с.
2. Дональд Э. Кнут. Искусство программирования. Том 1. Основные ал-
горитмы 3-е издание. – СПб.:Вильямс, 2014. – 720 с.
3. Дональд Э. Кнут. Искусство программирования, том 2. Получислен-
ные алгоритмы 3-е издание. – СПб.:Вильямс, 2015. – 832 с.
4. Технология программирования: учебник/ Г.С. Иванова. –
М.:КНОРУС, 2013. – 336 с.
5.2. Дополнительная литература:
1. Скиена С. Алгоритмы. Руководство по разработке. – 2-е изд.: Пер. с
англ. – СПб.: БХВ-Петербург, 2015. – 720 с.
2. Роберт Мартин. Чистый код: создание, анализ, рефакторинг. Библио-
тека программиста. – СПб.: Питер, 2014 – 464 с.
3. Кормен Т., Леверсон Ч., Ртвест Р. Алгоритмы. Построение и анализ. –
М.; МЦНМО, 2013. – 960 с.
4. Вирт Н. Алгоритмы и структуры данных: Пер. с англ. – 2-е изд., испр.
– СПб.: Невский Диалект, 2013. – 352 с.
5. Глаголев В.А. Разработка технической документации: Руководство
для технических писателей и локализаторов. – СПб.: Питер, 2015. – 192 с.

5.3. Методическая литература


Методические пособия к проведению лабораторных занятий
5.4. Интернет-ресурсы
www.microsoft.com – сайт компании Microsoft
www.embarcadeo.com – сайт компании Embarcadero
http://algolist.manual.ru/ – сайт, посвящённый разработке алгоритмов

20
5.5. Программное обеспечение
1. Microsoft Visio 2010
2. Embarcadero RAD Studio XE4
3. Microsoft Visual Studio 2010

21