Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Информатика Методические указания по выполнению лабораторных работ

Работа добавлена на сайт samzan.net: 2016-03-13

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 21.5.2024

Министерство образования и науки Российской Федерации

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

«Тамбовский государственный технический университет»
(ФГБОУ ВПО «ТГТУ»)

Утверждено

На заседании кафедры «Информационные системы и защита информации» 

протокол № 1 от  28. 08 . 2012  г.

Заведующий кафедрой

  О.Г. Иванова

Вводится в действие с

«  01  » сентября 20 12 г.

Методические указания по

выполнению лабораторных работ

по учебной дисциплине

 Информатика

(наименование дисциплины в соответствии с утвержденным учебным планом подготовки)

Для студентов, обучающихся по специальности:

 230201 Информационные системы и технологии

(шифр и наименование образовательной программы)

Специализация:

 

(наименование специализации)

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

 Очная, заочная  

Составитель:

 доцент Шахов Николай Гурьевич

(должность, фамилия, имя, отчество составителя программы)

Тамбов 2012

Содержание

  1.  Инструкция по мерам безопасности и правилам поведения в компьютерном классе….3
  2.  Методические указания по выполнению лабораторных работ………………..…..……..4
  3.  Лабораторная работа № 1 - Основы работы с персональным компьютером……………5
  4.  Лабораторная работа № 2 - Основная память………………………………….………….8
  5.  Лабораторная работа № 3 - Запоминающие устройства большой емкости…………….10
  6.  Лабораторная работа № 4 - Представление чисел……………..……………………...…19
  7.  Лабораторная работа № 5 - Представление текста, изображений и звука…..………...37
  8.  Лабораторная работа № 6 - Сжатие данных………………….………………………….49
  9.  Лабораторная работа № 7 - Машинный язык…………………………………….……...73
  10.  Лабораторная работа № 8 - Машинные команды……………….……………….……....83
  11.  Лабораторная работа № 9 - Обработка данных…………………..…………….………..92
  12.  Лабораторная работа № 10 - Настройка среды операционной системы…….………..102
  13.  Лабораторная работа № 11 – Служба World Wide Web…….…….…………….…….....65
  14.  Лабораторная работа № 12 - Электронная почта..……………………………….…….121
  15.  Лабораторная работа № 13 - Представление алгоритма……………………………….127
  16.  Лабораторная работа № 14 - Создание алгоритма……………………...……………...144
  17.  Лабораторная работа № 15 - Итерационные структуры в алгоритмах…………….....158
  18.  Лабораторная работа № 16 - Рекурсивные структуры в алгоритмах……………...….174
  19.  Лабораторная работа № 17 - Структурное программирование………………………..181
  20.  Лабораторная работа № 18 - Программные модули в языках программирования…..199
  21.  Лабораторная работа № 19 - Специализированные типы данных………………...…..217
  22.  Лабораторная работа № 20 - Последовательные списки……………………………….232
  23.  Лабораторная работа № 21 - Связанные списки…..…………………….……....……...242
  24.  Лабораторная работа № 22 - Стеки……..………………………………………….……261
  25.  Лабораторная работа № 23 - Очереди……..……………………….…………………...268
  26.  Лабораторная работа № 24 - Деревья……..……………………………………….……282
  27.  Лабораторная работа № 25 - Ввод-вывод в файл…..…………………………….…….299
  28.  Лабораторная работа № 26 - Индексация данных…..…………………………….……310
  29.  Лабораторная работа № 27 - Хэширование данных…..………………………….…….324
  30.  Лабораторная работа № 28 - Создание таблиц баз данных………………..…….…….344
  31.  Лабораторная работа № 29 - Управление данными…..……………………….……….365
  32.  Лабораторная работа № 30 - Машины и интеллект…..……………………….……….373
  33.  Лабораторная работа № 31 - Искусственные нейронные сети………………….....…..385
  34.  Лабораторная работа № 32 - Машины Тьюринга….………………………..………….405
  35.  Лабораторная работа № 33 – Алгоритмы криптографической защиты информации…

Инструкция

по мерам безопасности и правилам поведения в компьютерном классе

Общее положения:

· К работе в компьютерном классе допускаются лица, ознакомленные с данной инструкцией по технике безопасности и правилам поведения.

· Работа студентов в компьютерном классе разрешается только в присутствии преподавателя (инженера, лаборанта).

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

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

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

Перед началом работы необходимо:

· Убедиться в отсутствии видимых повреждений на рабочем месте;

· Разместить на столе тетради, учебные пособия так, что бы они не мешали работе на компьютере;

· Принять правильною рабочую позу.

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

При работе в компьютерном классе категорически запрещается:

· Находиться в классе в верхней одежде;

· Класть одежду и сумки на столы;

· Находиться в классе с напитками и едой;

· Присоединять или отсоединять кабели, трогать разъемы, провода и розетки;

· Передвигать компьютеры и мониторы;

· Открывать системный блок;

· Включать и выключать компьютеры самостоятельно без преподавателя и лаборанта.

· Пытаться самостоятельно устранять неисправности в работе аппаратуры;

· Перекрывать вентиляционные отверстия на системном блоке и мониторе;

· Ударять по клавиатуре, нажимать бесцельно на клавиши;

· Класть книги, тетради и другие вещи на клавиатуру, монитор и системный блок;

· Удалять и перемещать чужие файлы;

· Приносить и запускать компьютерные игры.

Находясь в компьютерном классе, студенты обязаны:

· Соблюдать тишину и порядок;

· Выполнять требования преподавателя и лаборанта;

· Находясь в сети работать только под своим именем и паролем;

· Соблюдать режим работы (согласно п. 9.4.2. Санитарных правил и норм);

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

· После окончания работы завершить все активные программы и корректно выключить компьютер;

· Оставить рабочее место чистым.

Работая за компьютером, необходимо соблюдать правила:

· Расстояние от экрана до глаз – 60 – 80 см (расстояние вытянутой руки);

· Вертикально прямая спина;

· Плечи опущены и расслаблены;

· Ноги на полу и не скрещены;

· Локти, запястья и кисти рук на одном уровне;

· Локтевые, тазобедренные, коленные, голеностопные суставы под прямым углом.

Требования безопасности в аварийных ситуациях:

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

· При появлении запаха гари, необычного звука немедленно прекратить работу, и сообщить преподавателю (лаборанту).

Методические указания по выполнению лабораторных работ

Лабораторный практикум по информатике содержит лабораторные работы по основным темам и используется для получения навыков по работе с информацией, системами счисления, офисным пакетом MS Office 2010, языком разметки HTML, одним из языков программирования высокого уровня. Все лабораторные работы выполняются на компьютере.

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

В представленных лабораторных работах используются ЭВМ, на которых установлена операционная система Windows 7, офисный пакет MS Office 2010, Интернет-браузер.

Лабораторная работа № 1.

Основы работы с персональным компьютером

Цель

Проверить уровень входных знаний и умений по школьному курсу дисциплины «Информатика».

Задание для самостоятельной подготовки

  1.  Повторить материал по устройству компьютера, а также основам работы в среде графических приложений[1], стр. 51-54.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

  •  системный блок;
  •  монитор;
  •  клавиатура;
  •  мышь.

Системный блок является основным узлом, поскольку внутри него установлены наиболее важные компоненты:

  •  материнская плата;
  •  жесткий диск;
  •  дисковод компакт – дисков;
  •  видеоадаптер (видеокарта);
  •  звуковая карта.

Материнская плата – основная плата персонального компьютера. На ней размещаются:

  •  центральный процессор (CPU — CentralProcessingUnit), или микропроцессор (часто просто процессор) – основная микросхема, выполняющая большинство математических  и логических операций;
  •  микропроцессорный комплект (чипсет) – набор микросхем, управляющих работой внутренних устройств компьютера и определяющих основные функциональные возможности материнской платы;
  •  шины – набор проводников, по которым происходит обмен сигналами между внутренними устройствами компьютера;
  •  оперативная память (оперативное запоминающее устройство, ОЗУ) – набор микросхем, предназначенных для временного хранения данных, когда компьютер включен;
  •  постоянное запоминающее устройство (ПЗУ) – микросхема, предназначенная для длительного хранения данных , в том числе и когда компьютер выключен;
  •  разъемы для подключения дополнительных устройств (слоты).

Жесткий диск  (HDD) – основное устройство для долговременного хранения больших объемов данных и программ.

Контроллер – аппаратно – логическое устройство для управления HDD.

Основные параметры HDD:

  •  емкость (зависит от технологии изготовления);
  •  производительность (зависит от интерфейса связи с материнской платой).

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

Тип диска   Длина волны, нм   Емкость

CD, CD-R,             780                                650 Мбайт

CD-RW

DVD, DVD-R,        635                                4,7  Гбайт  

DVD-RW

Blu-Ray 405                                25 Гбайт

Основной параметр – скорость чтения данных в единицах, кратных 150 Кбайт/с (музыкальный CD).

Видеокарта (видеоадаптер) – устройство с функциями видеоконтроллера, видеопроцессора, видеопамяти и видеоускорителя, образующего совместно с монитором видеоподсистему компьютера. Обеспечивает по выбору:

  •  цветовое разрешение (до 16,7 млн цветов);
  •  разрешение экрана из стандартного ряда значений (1024х768 и выше), а также аппаратное преобразование данных в микросхемах видеоускорителя.

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

Основной параметр – разрядность, определяющая количество битов, используемых при преобразовании сигналов из аналоговой формы в цифровую и наоборот. Чем выше разрядность, тем меньше погрешность, связанная с оцифровкой и выше качество звука. Наиболее распространены 16 и 32 разрядные карты.

Микропроцессор состоит из нескольких блоков, которые располагаются в корпусе микропроцессора. Наиболее важные из них — это устройство управления УУ, арифметически-логическое устройство АЛУ, регистры общего назначения (РОН), кэш-память первого L1 и второго L2 уровня и шины. Основные параметры процессора:рабочее напряжение, разрядность, рабочая тактовая частота,  коэффициент внутреннего  умножения тактовой частоты и размер кэш – памяти.

Оперативная память – это массив кристаллических ячеек, способных хранить данные. С точки зрения физического принципа действия различают динамическую память (DRAM) и статическую память (SRAM).

Ячейки динамической памяти можно представить в виде микроконденсаторов, способных накапливать заряд на своих обкладках. Это наиболее распространенный и экономичный вид памяти, именно поэтому он используется в качестве основной оперативной памяти компьютера.

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

Каждая ячейка памяти содержит восемь двоичных ячеек (один байт) и имеет свой адрес, который выражается числом. В большинстве современных процессоров предельный размер адреса составляет 32 разряда, следовательно, возможна непосредственная адресация к полю памяти размером 232 байт = 4 Гбайт. Количество оперативной памяти в современных компьютерах непрерывно увеличивается и в основном оно определяется требованиями операционной системы.

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

Микросхема ПЗУ хранит комплект программ, представляющих базовую систему ввода – вывода (BIOS – BasicInputOutputSystem), которая проверяет состав и работоспособность компьютерной системы и обеспечивает взаимодействие с клавиатурой, монитором, жестким диском. Программы позволяют наблюдать диагностические сообщения, сопровождающие запуск компьютера, а также вмешиваться в ход запуска с помощью клавиатуры.

Энергонезависимая память по технологии изготовления называемая CMOS. В нее можно заносить и изменять самостоятельно данные о жестких дисках, о процессоре и других устройствах материнской платы.

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

Задание

Используя один из редакторов, нарисуйте функциональную схему компьютера в формате А4, а затем уменьшите этот рисунок до формата А5.

Порядок выполнения работы

  1.  Нарисовать на листке бумаги функциональную схему компьютера и представить ее преподавателю.
  2.  Включить компьютер и используя графический редактор нарисовать на экране функциональную схему компьютера и представить ее преподавателю.
  3.  Сохранить схему на флэш – карте памяти.
  4.  Произвести масштабирование схемы до формата А5 и сохранить на флэш – карте памяти.
  5.  Ответить на контрольные вопросы.
  6.  Сделать выводы о проделанной работе.
  7.  Оформить отчет о проделанной лабораторной работе и защитить его у преподавателя.

Требования к отчету

Отчет должен содержать:

  •  Тему и цель работы.
  •  Исходное задание.
  •  Рисунки форматов А4 и А5 с функциональной схемой компьютера.
  •  Ответы на контрольные вопросы.
  •  Выводы о проделанной работе.

Контрольные вопросы

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

Лабораторная работа 2.

Основная память

Цель

Ознакомиться с устройствами, представляющими основную память компьютера.

Задание для самостоятельной подготовки

  1.  Изучить устройства, которые представляют основную память компьютера. [1], стр. 51-54.
    1.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

Задание к работе

  1.  Определить местонахождение оперативной памяти в системном блоке компьютера.
  2.  Определить местонахождение жестких дисков в системном блоке компьютера.
  3.  Определить местонахождение ПЗУ  в системном блоке компьютера.
  4.  Управляющая память. Назначение.
  5.  По маркировке определить производителя этих устройств и их тип.
  6.  Вычислить общий объем оперативной памяти.
  7.  Установите тип подключения жесткого диска в Вашем ПК?
  8.  Какие разъемы для подключения жестких дисков существуют?
  9.  Кеш – память. Назначение.
  10.  Магнитные диски. Виды магнитных дисков.
  11.  Что такое энергозависимость?
  12.  Какая память является энергозависимой?
  13.  От размера какой памяти зависит скорость работы компьютера?
  14.  В какой области памяти хранится исполняемая в данный момент программа?
  15.  В какую память информация заносится в один раз (обычно в заводских условиях) и сохраняется постоянно (при включенном и выключенном компьютере)?
  16.  Составная часть оперативной памяти. Регистр. Описание.
  17.  Составная часть оперативной памяти. Триггер. Описание.
  18.  Буферная память. Назначение.
  19.  Какой объем оперативной памяти поддерживает 32 разрядная ОС?
  20.  Какое устройство памяти хранит операционную систему?

Порядок выполнения работы

  1.  Убедитесь в том, что компьютерная система обесточена (при необходимости, отключите систему от сети).
  2.  Установите местоположение разъемов для установки модулей оперативной памяти. Выясните их количество и тип используемых модулей (DIMM или SIMM) ,установите количество контактов.
  3.  По маркировке определите тип и фирму-изготовителя модулей оперативной памяти.
  4.  Установите местоположение жестких дисков (винчестеров). Выясните их количество и тип подключения (SATA или IDE).
  5.  По маркировке определите тип и фирму-изготовителя винчестера.
  6.  Установите местоположение микросхемы ПЗУ.
  7.  По наклейке на ней определите производителя системы BIOS данного компьютера.
  8.  Заполните отчетные таблицы:

 

Изготовитель

Модель

Оперативная память

 

 

Микросхема ПЗУ

 

 

Жесткий диск

 

 

Количество разъемов модулей оперативной памяти

Количество физических жестких дисков

SIMM

DIMM

SATA

IDE

Требования к отчету

Отчет должен содержать:

  1.  Задание и данные варианта работы;
  2.  Краткое описание используемых технических и программных средств;
  3.  Обоснование принятых решений;
  4.  Заполненные таблицы п.п.8;
  5.  Ответы на контрольные вопросы;
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Типы электронных плат управления работой компьютера;
  2.  Основные характеристики материнской платы;
  3.  Устройства, расположенные на материнской плате, их характеристики;
  4.  Характеристики шин - тип подключаемых устройств, скорость передачи данных;
  5.  Контроллеры и адаптеры, их назначение и основные характеристики.

Лабораторная работа № 3.

«Запоминающие устройства большой емкости»

Цель

Изучить состав и основные характеристики запоминающих устройств большой емкости

Задание для самостоятельной подготовки

  1.  Изучитьустройства, которые представляют основную память компьютера. [1], стр. 51-54, [2], стр.71-75, 92-93.
    1.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

Одним из наиболее распространенных запоминающих устройств сегодня является магнитный диск (magneticdisk), в котором тонкий вращающийся диск с магнитным покрытием используется как носитель информации. Головки чтения/записи располагаются над и/или под диском, так что, когда диск вращается, каждая головка очерчивает кольцо на верхней или нижней поверхности диска, называемое дорожкой (track). При различном положении головок чтения/записи осуществляется доступ к различным дорожкам. В большинстве случаев запоминающая система состоит из нескольких дисков, установленных на общем шпинделе, один над другим на расстоянии, достаточном для прохождения между ними головок чтения/записи. Каждый раз, когда положение головок чтения/записи меняется, становится доступным новый набор дорожек, который называется цилиндром (cylinder).

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

Таким образом, запоминающая система диска состоит из отдельных секторов, каждый из которых содержит независимую последовательность битов. Число дорожек и секторов на дорожке различается в зависимости от накопителя. Размер сектора обычно не больше нескольких килобайтов, общепринятыми являются секторы размером 512 или 1024 байта.

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

Диски большой емкости, способные вмещать гигабайты информации, состоят их 5—10 жестких дисков, установленных на общем шпинделе. Из-за того, что диски, используемые в этих устройствах, жесткие, и само устройство называется жестким диском (harddisk, или HDD), в отличие от гибких дисков. Для большей скорости вращения головки чтения/записи в этих устройствах не соприкасаются с диском, а «плавают» над его поверхностью. Расстояние между головками и диском настолько мало, что даже пылинка может помешать работе и разрушить и диск, и головку (это явление называется аварией головок (headcrash)). Поэтому накопитель на жестких дисках помещается в футляр, запаянный на заводе.

Чтобы оценить качество накопителя на дисках, используется несколько параметров, среди которых наибольшее значение имеет емкость и размер кэш-памяти.

Другая распространенная технология хранения данных — компакт-диски (compactdisks). Эти диски диаметром 12 см состоят из отражающего материала, покрытого прозрачным защитным слоем. Запись информации на них осуществляется посредством изменения структуры их отражающего слоя. Информация извлекается с диска при помощи лазерного луча, который контролирует отличия структуры отражающего слоя диска по мере его вращения. Технология производства компакт-дисков первоначально применялась для звукозаписи, при этом использовался формат, известный как CD-DA (compactdiskdigitalaudio — компакт-диск с цифровой звукозаписью). Компакт-диски, которые применяются сегодня для хранения данных, имеют этот же формат. А именно информация на этих дисках хранится на единственной спиральной дорожке, похожей на спиральный желобок в старых грампластинках. (Однако в отличие от пластинок дорожка диска находится внутри, а не на поверхности.) Дорожка разделена на отрезки, которые называются секторами. Каждый сектор имеет свой идентифицирующий маркер и емкость 2 Кбайт, что составляет 1/75 секунды звукозаписи.

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

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

Емкость обычных компакт-дисков составляет 600-700 Мбайт. Однако другой формат DVD (DigitalVersatileDisk — универсальный цифровой диск) имеет емкость порядка 4,7 Гбайт. Диск же в формате BluRayимеет емкость порядка 25 Гбайт и предназначен для хранения видеоинформации высокого качества (1920 х 1080 пикселов). Однако широкого распространения последнего формата пока не происходит вследствие высокой цены BluRay дисков.

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

Современный вариант с USB 2.0 имеет пропускную способность до 480 Мбит/с. Устройство имеет минимальные размеры и напоминает автомобильный брелок и допускает «горячее» подключение к разъему USB. Может служить не только «переносчиком» файлов, но и работать как обычный накопитель — с него можно запускать приложения, воспроизводить музыку и сжатое видео, редактировать и создавать файлы.

Задание к работе

  •  Определить местонахождение жесткого диска в системном блоке компьютера (в ноутбуке).
  •  По маркировке определить производителя этих устройств и их тип.
  •  Используя сеть Интернет установите основные характеристики жесткого диска.
  •  Вычислить заявленный и реальный объем жесткого диска.
  •  Сравните объемы кэш-памяти вашего жесткого диска и устройств аналогичного типа. Каким образом это влияет на производительность компьютера?
  •  Установите тип подключения жесткого диска в Вашем ПК?
  •  Какие разъемы для подключения жестких дисков существуют?

Порядок выполнения работы

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

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Заполненную таблицус характеристиками жесткого диска и основными результатами исследования.
  3.  Ответы на контрольные вопросы.
  4.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Какое устройство имеет жесткий диск?
  2.  Какие существуют типы подключений жесткого диска? От чего они зависят и что определяют?
  3.  Какие основные характеристики жесткого диска? Как они влияют на производительность компьютера?
  4.  Какое назначение имеет кэш-память жесткого диска?
  5.  Сделайте краткий анализ современного состояния и перспектив развития устройств хранения данных.

Лабораторная работа № 4.

Представление чисел

Цель

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

Задание для самостоятельной подготовки

1. Изучить представления чисел в компьютере [1], стр. 49, 69-82.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Двоичное представление — это способ записи числовых значений, в котором используются только 0 и 1, а не 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9, как в традиционной, десятичной, системе счисления. В двоичном представлении каждая позиция в записи числа также, как и в десятичной соответствует определенному разряду, при движении по записи числа влево вес разряда каждый раз увеличивается в два раза. Более точно, вес разряда последнего числа справа равен единице (2°), вес разряда следующего числа равен двум (21), следующего — четырем (22), следующего — восьми (23) и т. д. Например, в двоичной записи 1011 самая крайняя справа 1 соответствует весу разряда, равному единице, следующая единица — весу разряда, равному двум, 0 соответствует весу разряда, равному четырем, а самая крайняя слева 1 — весу разряда, равному восьми.

Последовательность двоичных записей, соответствующих десятичным числам от 0 до 8, выглядит следующим образом: 0, 1, 10, 11, 100, 101, 110, 111, 1000.

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

Шаг 1. Разделите число на два и запишите остаток деления.

Шаг 2. До тех пор пока частное не равно нулю, продолжайте делить частные на два и записывать остаток.

Шаг 3. Когда частное станет равно нулю, двоичная запись числа будет состоять из остатков деления, выписанных справа налево в том порядке, в каком они были получены.

Для хранения целых чисел принята система кодирования, называемая представлением в дополнительном коде, потому что она дает возможность кодирования и положительных, и отрицательных чисел. Для хранения чисел с дробной частью, таких как 41/2 используется другая форма, называемая представлением чисел с плавающей точкой. Таким образом, отдельное значение (например, 25) может быть представлено различными последовательностями битов (как символ, закодированный в стандарте ASCII; в представлении в дополнительном коде или в форме с плавающей точкой, как 250/2), и наоборот, отдельную последовательность битов можно интерпретировать по-разному.

При представлении дробей используется точка, чтобы отделить целую часть от дробной части. Цифры слева от точки являются целой частью числа и записываются в двоичном представлении по принципу, изложенному выше. Цифры справа от точки являются дробной частью числа и записываются так же, как целые, с той лишь разницей, что каждой позиции в записи числа соответствует разряд, вес которого является дробным числом. То есть вес разряда, соответствующего первой позиции после точки, равен 1/2, второй позиции — 1/4, следующей — 1/8 и т. д. Для сложения двух чисел применяется методика, которая используется и для целых чисел. То есть, чтобы получить сумму двух дробных чисел, записываем числа одно под другим так, чтобы точки находились в одном столбце, и выполняем те же действия, как с целыми числами. Например, числа 10.011 и 100.101 в сумме дают 111.000:

+ 10.011

100.101

111.000

Наиболее распространенной системой представления целых чисел в современных компьютерах является представление в двоичном дополнительном коде. Эта система использует фиксированное число битов для представления числового значения. В современном оборудовании принято использовать представление, при котором каждому значению отводится 32 бита. В представлении в двоичном дополнительном коде крайний слева разряд обозначает знак числа. Поэтому его часто называют знаковым разрядом. Знаковый разряд отрицательных чисел равен 1, а положительных чисел — 0.

Существует удобное соотношение между записью положительного и отрицательного чисел, одинаковых по модулю. Они совпадают, если их читать справа налево, до первой единицы включительно, а с этого места они являются дополнениями друг друга (дополнением набора битов является набор битов, который получается путем замены всех нулей на единицы и наоборот; например, 0110 и 1001 — дополнения друг друга). Например, в 4-битовом представлении записи чисел 2 и -2 заканчиваются на 10, но запись числа 2 начинается с 00, а числа -2 — с 11. Это наблюдение помогает найти алгоритм для получения записи отрицательного числа из записи положительного и наоборот, когда эти числа равны по модулю. Мы просто переписываем исходную последовательность до тех пор, пока не будет переписана единица, затем мы переписываем оставшиеся разряды, заменяя их дополнениями (рис. 2). Обратите внимание, что самое маленькое отрицательное число в представлении в дополнительном коде не имеет положительного эквивалента.

Рисунок 2 – Представление числа -6 в 4-битовом дополнительном коде

Понимание основных свойств представления в двоичном дополнительном коде ведет к алгоритму его декодирования. Если знаковый бит записи равен 0, то нужно просто читать значение, как если бы эта последовательность была двоичной записью числа. Например, 0110 является представлением числа 6, потому что 110 является двоичной записью шести. Если знаковый разряд равен 1, значит, перед нами отрицательное число и нам остается только найти его модуль. Переписываем исходную последовательность справа налево, пока не будет переписана 1, затем переписываем оставшиеся биты, дополняя их. И, наконец, расшифровываем полученную последовательность, как если бы она была двоичной записью числа.

Например, для того чтобы перевести последовательность 1010 в десятичную систему счисления, мы сначала определяем, что перед нами отрицательное число, так как знаковый разряд равен 1. Следовательно, переписываем запись как 0110. Определяем, что она является представлением числа 6, и делаем вывод о том, что исходный набор битов является представлением числа -6.

Сложение в двоичном дополнительном коде. Для сложения чисел в двоичном дополнительном коде применяется такой же алгоритм, как для двоичного сложения, только в этом случае все коды, включая результат операции, будут иметь одинаковую длину. Это означает, что если в результате сложения появляется дополнительный бит с левого края, он будет отсечен. Именно поэтому 0101 и 0010 в сумме дают 0111, а сумма 0111 и 1011 равна 0010 (0111 + 1011 = 10010, которая усекается до 0010).

Рассмотрим три примера сложения в дополнительном коде (рис. 3). В каждом случае десятичная запись была представлена 4-битовым кодом, а результат сложения опять переведен в десятичную систему счисления.

Рисунок 3 – Сложение чисел в двоичном дополнительном коде

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

111 3

110 2

101 1

100 0

011 -1

010 -2

001 -3

000 -4

Рисунок 4 - 3-битовое представление с избытком

Очевидно, что 3-битовое представление с избытком является представлением с избытком четыре, а 4-битовое представление с избытком является представление с избытком 8. Для того чтобы понять, почему это так, сначала переведите коды в десятичную систему счисления, как обычный двоичный код, и сравните полученные значения со значениями в таблице. В каждом случае вы обнаружите, что полученный результат превосходит код в представлении с избытком на восемь. Например, последовательность 1100 в двоичной системе является кодом 12, но в представлении с избытком она является кодом 4; последовательность 0000 в двоичной системе является кодом 0, а в представлении с избытком — кодом 8. Можно заметить, что код с одной 1 в позиции старшего разряда находится примерно посередине списка. Пусть он будет представлением нуля; коды до него используются для представления 1, 2, 3 и т. д., коды после него используются для -1, -2, -3 и т. д. Окончательный вариант таблицы 4-битовых кодов изображен на рис. 1.23. Можно заметить, что число 5 имеет код 1101, а число -5 имеет код 0011. Обратите внимание на то, что различие между представлением в двоичном дополнительном коде и избыточном коде заключается в том, что знаковый разряд у них имеет противоположное значение.

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

Рисунок 5 – Структура представления записи числа с плавающей точкой на примере 1 байта

В этой структуре старший разряд бита является знаковым разрядом. Как и раньше, 0 в позиции знакового разряда означает, что число неотрицательное, 1 в позиции знакового разряда означает, что число отрицательное. Следующие три бита являются полем порядка в представлении с избытком 4, а оставшиеся четыре бита являются полем мантиссы.

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

Таблица 1 - Шестнадцатеричная система счисления

Последовательность

битов

Шестнадцатеричное

представление

0000

0

0001

1

0010

2

0011

3

0100

4

0101

5

0110

6

0111

7

1000

8

1001

9

1010

A

1011

B

1100

C

1101

D

1110

E

1111

F

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

Задание

1. Перевести числа из десятичной системы счисления в двоичную и шестнадцатеричную систему счисления.

2. Перевести числа в десятичную систему счисления.

3. Сложить числа.

4.Найти десятичный эквивалент чисел, заданных в представлении с плавающей точкой.

5. Перевести числа в представлении с плавающей точкой.

Примечание. В заданиях 3–5 проверять правильность вычислений переводом исходных данных и результатов в десятичную систему счисления.

Вариант 1

1. а) 860(10); б) 785(10); в) 149,375(10); г) 953,25(10); д) 228,79(10).

2. а) 10001010(2); б) 11100111(2); в) 11010110(ДДК); г) 111111100(ДДК). 

3. а) 1101100000(2) + 10110110(2); б) 101110111(2) + 1000100001(2); в) 1001000111,01(2)+100001101,101(2).

4. а) 10110010; б) 11100011.

5. а) 11/2; б) 42/3.

Вариант 2

1. а) 250(10); б) 757(10); в) 711,25(10); г) 914,625(10); д) 261,78(10).

2. а) 1111000(2); б) 1111000000(2); в) 11101100(ДДК); г) 10011110(ДДК);

3. а) 1010101(2)+10000101(2); б) 1111011101(2)+101101000(2); в) 100100111,001(2)+100111010,101(2);

4. а) 10010010; б) 11101110.

5. а) 13/4; б) 41/5.

Вариант 3

1. а) 759(10); б) 265(10); в) 79,4375(10); г) 360,25(10); д) 240,25(10).

2. а) 1001101(2); б) 10001000(2); в) 10011001(ДДК); г) 01111010(ДДК). 

3. а) 100101011(2)+111010011(2); б) 1001101110(2)+1101100111(2); в) 1010000100,1(2)+11011110,001(2).

4. а) 11001100; б) 11100011.

5. а) 11/2 ; б) 31/4.

Вариант 4

1. а) 216(10); б) 336(10); в) 741,125(10); г) 712,375(10); д) 184,14(10).

2. а) 1100000110(2); б) 1100010(2); в) 01011010(ДДК); г) 10101000(ДДК).

3. а) 101111111(2)+1101110011(2); б) 10111110(2)+100011100(2); в) 1101100011,0111(2)+1100011,01(2).

4. а) 10101011; б) 01010001.

5. а) 15/7; б) 11/4.

Вариант 5

1. а) 530(10); б) 265(10); в) 597,25(10); г) 300,375(10); д) 75,57(10).

2. а) 101000111(2); б) 110001001(2); в) 01001101(ДДК); г) 10111101(ДДК).

3. а) 1100011010(2)+11101100(2); б) 10111010(2)+1010110100(2); в) 1000110111,011(2)+1110001111,001(2).

4. а) 01100101; б) 11011010.

5. а) 25/7; б) 15/6.

Вариант 6

1. а) 945(10); б) 85(10); в) 444,125(10); г) 989,375(10); д) 237,73(10).

2. а) 110001111(2); б) 111010001(2); в) 01001101(ДДК); г) 10000100(ДДК).

3. а) 1000011101(2)+101000010(2); б) 100000001(2)+1000101001(2); в) 101111011,01(2)+1000100,101(2).

4. а) 01000101; б) 10111010.

5. а) 35/7; б) 25/6.

Вариант 7

1. а) 287(10); б) 220(10); в) 332,1875(10); г) 652,625(10); д) 315,21(10).

2. а) 10101000(2); б) 1101100(2); в) 01001000(ДДК); г) 11100101(ДДК).

3. а) 1100110(2)+1011000110(2); б) 1000110(2)+1001101111(2); в) 101001100,101(2)+1001001100,01(2).

4. а) 10111111; б) 01110011.

5. а) 51/2; б) 12/5.).

Вариант 8

1. а) 485(10); б) 970(10); в) 426,375(10); г) 725,625(10); д) 169,93(10).

2. а) 10101000(2); б) 101111110(2); в) 10101010(ДДК); г) 11110011(ДДК).

3. а) 1010100111(2)+11000000(2); б) 1110010010(2)+110010111(2); в) 1111111,101(2)+101010101,101(2).

4. а) 01010100; б) 10110101.

5. а) 13/4 ; б) 41/2.

Вариант 9

1. а) 639(10); б) 485(10); в) 581,25(10); г) 673,5(10); д) 296,33(10).

2. а) 1011000011(2); б) 100010111(2); в) 1100101101,1(ДДК); г) 1000000000,01(ДДК).

3. а) 1000010100(2) + 1101010101(2); б) 1011001010(2)+101011010(2); в) 1110111000,101(2)+1101100011,101(2).

4. а) 01111100; б) 10110001.

5. а) 21/8; б) 51/2 .

Вариант 10

1. а) 618(10); б) 556(10); в) 129,25(10); г) 928,25(10); д) 155,45(10).

2. а) 1111011011(2); б) 1011101101(2); в) 01001110(ДДК); г) 10111100(ДДК).

3. а) 11111010(2)+10000001011(2); б) 1011010(2)+1001111001(2); в) 10110110,01(2)+1001001011,01(2);

4. а) 01111011; б) 10001101.

5. а) 31/2; б)  41/3.

Вариант 11

1. а) 772(10); б) 71(10); в) 284,375(10); г) 876,5(10); д) 281,86(10).

2. а) 1000001111(2); б) 1010000110(2); в) 01011001(ДДК); г) 10010011(ДДК).

3. а) 1100111(2)+1010111000(2); б) 1101111010(2)+1000111100(2); в) 1111101110,01(2)+1110001,011(2).

4. а) 01010101; б) 10001000.

5. а) 41/3; б) .11/5

Вариант 12

1. а) 233(10); б) 243(10); в) 830,375(10); г) 212,5(10); д) 58,89(10).

2. а) 1001101111(2); б) 1000001110(2); в) 01111100(ДДК); г) 11010101(ДДК).

3. а) 1101111001(2)+1010010101(2); б) 1111001001(2)+1001100100(2); в) 100110010,011(2)+110001000,011(2).

4. а) 01000100; б) 11010001.

5. а)23/4 ; б)  31/3.

Вариант 13

1. а) 218(10); б) 767(10); в) 894,5(10); г) 667,125(10); д) 3,67(10).

2. а) 1111100010(2); б) 1000011110(2); в) 01011001(ДДК); г) 10011110(ДДК).

3. а) 1000011111(2)+1111100(2); б) 1011100011(2)+111110110(2); в) 111111100,1(2)+1011100100,1(2).

4. а) 01101001; б) 11100101.

5. а) 13/4; б) 31/.

Вариант 14

1. а) 898(10); б) 751(10); в) 327,375(10); г) 256,625(10); д) 184,4(10).

2. а) 101110100(2); б) 1111101101(2); в) 11101001(ДДК); г) 10111110(ДДК).

3. а) 1001000000(2)+101010110(2); б) 11000010(2)+1001110100(2); в) 1011101110,1(2)+11100101,01(2).

4. а) 01010010; б) 11111101.

5. а) 31/4; б) 53/8.

Вариант 15

1. а) 557(10); б) 730(10); в) 494,25(10); г) 737,625(10); д) 165,37(10).

2. а) 101001101(2); б) 1110111100(2); в) 01001000; г) 10001101(ддк).

3. а) 1101100001(2)+1001101110(2); б) 1101010101(2)+101011001(2); в) 1101111110,011(2)+1100101101,1011(2).

4. а) 01111000; б) 11001101.

5. а) 32/5; 71/2.

Вариант 16

1. а) 737(10); б) 92(10); в) 934,25(10); г) 413,5625(10); д) 100,94(10).

2. а) 1110000010(2); б) 1000100(2); в) 110000100,001(ДДК); г) 1001011111,00011(ДДК).

3. а) 11110100(2)+110100001(2); б) 1101110(2)+101001000(2); в) 1100110011,1(2)+111000011,101(2).

4. а) 01000101; б) 10010110.

5. а) 42/3; б) 51/2.

Вариант 17

1. а) 575(10); б) 748(10); в) 933,5(10); г) 1005,375(10); д) 270,44(10).

2. а) 1010000(2); б) 10010000(2); в) 01111010000(ДДК); г) 101000011,01(ДДК).

3. а) 1011110101(2)+1010100110(2); б) 1001100011(2)+1110010010(2); в) 1111110100,01(2)+110100100,01(2).

4. а) 01100111; б) 11011110.

5. а) 24/5; б) 13/4.

Вариант 18

1. а) 563(10); б) 130(10); в) 892,5(10); г) 619,25(10); д) 198,05(10).

2. а) 11100001(2); б) 101110111(2); в) 1011110010(ДДК); г) 1100010101(ДДК).

3. а) 1100100011(2)+1101001111(2); б) 111101111(2)+10010100(2); в) 1010010000,0111(2)+111010100,001(2).

4. а) 01110011; б) 10110001.

5. а) 14/5; б) 53/4.

Вариант 19

1. а) 453(10); б) 481(10); в) 461,25(10); г) 667,25(10); д) 305,88(10).

2. а) 111001010(2); б) 1101110001(2); в) 1001010100(ДДК); г) 111111110(ДДК).

3. а) 101110001(2)+101111001(2); б) 1110001110(2)+1100110111(2); в) 10000011010,01(2)+1010010110,01(2).

4. а) 01111001(2); б) 11101010.

5. а) 14/5; б) 21/6.

Вариант 20

1. а) 572(10); б) 336(10); в) 68,5(10); г) 339,25(10); д) 160,57(10).

2. а) 1010110011(2); б) 1101110100(2); в) 1010101(ДДК); г) 1101000(ДДК).

3. а) 10001000(2)+1011010010(2); б) 111110011(2)+111110000(2); в) 1010001010,1011(2)+1101010100,011(2).

4. а) 01101110; б) 11000101.

5. а) 51/2; б) 14/5.

Порядок выполнения работы

Пример 1. Перевести число 13 из десятичной системы счисления в двоичную (получить пять знаков после запятой в двоичном представлении).

Сначала делим тринадцать на два, получаем частное, равное шести, и единицу в остатке; так как частное не равно нулю, делим его на два в соответствии с шагом 2 алгоритма перевода.

Рисунок 6 – Получение двоичной записи числа 13

В результате имеем новое частное, равное трем, и ноль в остатке. Это частное также не равно нулю, поэтому делим его на два, получая частное, равное единице, и два в остатке. Еще раз делим частное (единицу) на два, в этот раз частное равно нулю, а остаток единице. Так как мы получили в результате деления ноль, то переходим к третьему шагу и получаем двоичную запись исходного значения (тринадцать), которая имеет вид 1101.

Пример 2. Перевести число 1000001 в десятичную систему счисления:

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

1000001(2) =1×26+0×25+0×24+0×23+0×22+0×21+1×20=64+1=65(10).

Замечание. Если в каком-либо разряде стоит нуль, то соответствующее слагаемое можно опускать.

Пример 3. Сложить числа 00111010 и 00011011.

Решение задачи

+00111010

 00011011

мы начинаем со сложения 0 и 1 в последнем столбце, получаем единицу, которую записываем под столбцом. Теперь мы складываем две единицы из следующего столбца, получая 10. Записываем 0 под столбцом, а 1 — над следующим столбцом. На этом этапе процесс решения выглядит следующим образом:

         1

00111010

00011011

           01

Складываем 1, 0 и 0, получаем 1 и записываем ее под этим столбцом. Следующие две единицы в сумме дают 10, записываем 0 под столбцом и переносим 1 в следующий столбец. Теперь решение выглядит так:

       1

+00111010

 00011011

         0101

Три единицы в следующем столбце в сумме дают 11, записываем младшую 1 под столбцом, а другую переносим в следующий столбец. Теперь складываем 1, 1 и 0, получаем 10. Снова записываем 0 под столбцом, а 1 — в следующий столбец.

   1

+00111010

 00011011

     010101

Складываем 1, 0 и 0 из предпоследнего столбца, получаем 1, записываем ее под столбцом. И, наконец, сумма чисел в последнем столбце равна 0, записываем ее под столбцом. Окончательное решение выглядит так:

+00111010.

Пример 4. Найти десятичный эквивалент чисел, заданных в представлении с плавающей точкой

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

.1011.

Затем извлекаем порядок (110) и переводим его как 3-битовое представление с избытком в десятичную систему счисления. В нашем случае код порядка является представлением 2. Перемещаем разделительную точку на 2 бита вправо (отрицательный порядок означает, что точку нужно перемещать влево). Следовательно, мы имеем последовательность

10.11,

которая является двоичной записью дроби 23/4. Затем обращаем внимание на то, что знаковый разряд равен 0, следовательно, перед нами неотрицательное число. Делаем вывод, что в байте 01101011 хранится число 23/4.

В качестве еще одного примера рассмотрим байт 10111100. Выписываем мантиссу

.1100

и перемещаем точку на один бит влево, так как порядок (011) является кодом числа — 1. Имеем последовательность

.01100,

которая является кодом 3/8. Знаковый разряд исходной последовательности равен 1, значит, число отрицательное. Делаем вывод, что последовательность 10111100 является кодом - 3/8.

Пример 5. Чтобы записать число в представлении с плавающей запятой, выполняем действия, обратные предыдущим. Например, чтобы записать число 11/8, сначала выражаем его в двоичном представлении и получаем 1.001. Затем переписываем эту последовательность в область мантиссы слева направо, начиная с самой левой единицы в двоичной записи. На этом этапе байт выглядит следующим образом: _ _ _ _ 1 0 0 1

Теперь нужно заполнить поле порядка. Для этого представляем ман-тиссу с разделительной точкой слева и определяем число битов и направление, в котором нужно передвинуть точку, чтобы получить исходную двоичную запись. В нашем примере, чтобы получить 1.011, нужно передвинуть точку в .1001 на один бит вправо. Следовательно, порядок равен 1, поэтому записываем 101 (код 1 в представлении с избытком 4) в поле порядка. Наконец, записываем в позицию знакового разряда 0, потому что дробь неотрицательная. Окончательный байт выглядит так:

01011001.

Наиболее тонким моментом в преобразовании является заполнение поля мантиссы. Правило гласит: выписывать последовательность разрядов двоичной записи слева направо, начиная с самой левой 1 в двоичной записи. В качестве примера рассмотрим процесс записи числа 3/8, двоичное представление которого .011. В этом случае мантиссой будет

_ _ _ _ 1 1 0 0,

а не

_ _ _ _ 0 1 1 0.

Мантисса имеет такой вид, потому что поле мантиссы заполняется, начиная с самой левой единицы, которая появляется в двоичном представлении. Это правило исключает возможность многократной записи одного значения. Оно также означает, что мантисса чисел, не равных нулю, будет всегда начинаться с 1. О таком представлении говорят, что оно нормализованное. Обратите внимание, что представление нуля является особым случаем: его представление с плавающей точкой состоит из одних нулей. Ошибка усечения. Рассмотрим проблему, которая возникает, когда мы пытаемся записать значение 25/8 в представлении с плавающей точкой, используя для него один байт памяти. Сначала записываем 25/8 в двоичном представлении, получаем 10.101. Но, когда мы переписываем его в поле мантиссы, нам не хватает места, и самая правая 1 (которая занимает позицию с весом разряда 1/8) теряется. Если мы на данном этапе будем игнорировать эту проблему и продолжим заполнение поля порядка, то в результате придем к последовательности 01101010, которая является представлением 21/2 вместо 25/8. То, что произошло, называется ошибкой усечения и означает, что часть числа потеряна, потому что поле мантиссы недостаточно велико.

Контрольные вопросы

  1.  Чему равен дополнительный код отрицательного числа?
  2.  С какой целью отрицательные числа записываются в виде дополнительного кода?
  3.  На что опирается способ представления чисел с плавающей запятой?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы
  2.  Задание
  3.  Выполненные задания с подробным ходом решения
  4.  Ответы на контрольные вопросы
  5.  Выводы о проделанной работе.

Лабораторная работа №5.

«Представление текста, изображений и звука»

Цель работы

Изучить методы кодирования текста, изображений и звука в двоичной системе счисления.

Задание для самостоятельной подготовки

1.Изучить особенности представления текста, изображений и звукав виде двоичного кода[1], стр. 61-68.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

В современных ЭВМ, в зависимости от типа операционной системы и конкретных прикладных программ, используются 8-разрядные и 16-разрядные (Windows 95, 98, NT) коды символов. Использование 8-разрядных кодов позволяет закодировать 256 различных знаков, этого вполне достаточно для представления многих символов, используемых на практике. При такой кодировке для кода символа достаточно выделить в памяти один байт. Так и делают: каждый символ представляют своим кодом, который записывают в один байт памяти.

В персональных компьютерах обычно используется система кодировки ASCII (AmericanStandardCodeforInformationInterchange - американский стандартный код для обмена информации). Он введен в 1963 г. и ставит в соответствие каждому символу семиразрядный двоичный код. Легко определить, что в коде ASCII можно представить 128 символов.

В системе ASCII закреплены две таблицы кодирования базовая и расширенная. Базовая таблица закрепляет значения кодов от 0 до 127, а расширенная относится к символам с номерами от 128 до 255.

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

Кодировка символов русского языка, известная как кодировка Windows-1251, была введена "извне" - компанией Microsoft, но, учитывая широкое распространение операционных систем и других продуктов этой компании в России, она глубоко закрепилась и нашла широкое распространение.

Другая распространённая кодировка носит название КОИ-8 (код обмена информацией, восьмизначный) - её происхождение относится к временам действия Совета Экономической Взаимопомощи государств Восточной Европы. Сегодня кодировка КОИ - 8 имеет широкое распространение в компьютерных сетях на территории России и в российском секторе Интернета.

Международный стандарт, в котором предусмотрена кодировка символов русского языка, носит название ISO (InternationalStandardOrganization - Международный институт стандартизации). На практике данная кодировка используется редко.

Если проанализировать организационные трудности, связанные с созданием единой системы кодирования текстовых данных, то можно прийти к выводу, что они вызваны ограниченным набором кодов (256). В то же время, очевидно, что если, кодировать символы не восьмиразрядными двоичными числами, а числами с большим разрядом то и диапазон возможных значений кодов станет на много больше. Такая система, основанная на 16-разрядном кодировании символов, получила название универсальной - UNICODE. Шестнадцать разрядов позволяют обеспечить уникальные коды для 65 536 различных символов - этого поля вполне достаточно для размещения в одной таблице символов большинства языков планеты.

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

Таблица, в которой всем символам компьютерного алфавита поставлены в соответствие порядковые номера (коды), называется таблицей кодировки.

Ниже приведены таблицы кодировки ASCII.

Рисунок1– Базовая таблица кодировки ASCII

Рисунок 2 –Кодировка Windows 1251

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

Рисунок 3–Двухмерное векторное изображение

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

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

Рисунок 4 –Трехмерное векторное изображение

Двухмерные векторные форматы очень хороши для-представления чертежей, диаграмм, шрифтов (или, если угодно, отдельных букв шрифта) и отформатированных текстов. Такие изображения удобно редактировать - изображения и их отдельные элементы легко поддаются масштабированию и другим преобразованиям. Примеры двухмерных векторных форматов - PostScript, PDF (PortableDocumentFormat, специализированное подмножество PostScript), WMF (WindowsMetaFile), PCL (PrinterControlLanguage, система команд принтеров, поддерживаемая большинством современных лазерных и струйных печатающих устройств). Примером векторного представления движущихся изображений является MacroMediaFlash. Трехмерные векторные форматы широко используются в системах автоматизированного проектирования и для генерации фотореалистичных изображений методами трассировки лучей и т. д.

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

Размер матрицы называется разрешением растрового изображения. Для печатающих устройств (и при растеризации изображений, предназначенных для таких устройств) обычно задается неполный размер матрицы, соответствующей всему печатному листу, а количество пикселов, приходящихся на вертикальный или горизонтальный отрезок длиной 1 дюйм; соответствующая единица так и называется - точки на дюйм (DPI, DotsPerInch).

Для черно-белой печати обычно достаточно 300 или 600 DPI. Однако принтеры, в отличие от растровых терминалов, не умеют манипулировать яркостью отдельной точки, поэтому изменения яркости приходится имитировать, разбивая изображение на квадратные участки и регулируя яркость относительным количеством черных и белых (или цветных и белых при цветной печати) точек в этом участке. Для получения таким способом приемлемого качества фотореалистичных изображений 300 DPI заведомо недостаточно, и даже бытовым принтерам приходится использовать гораздо более высокие разрешения, вплоть до 2400 DPI.

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

Рисунок 5– Растровое изображение

Наиболее широко используемые цветовые модели - это RGB (Red, Green, Blue - красный, зеленый, синий, соответствующие максимумам частотной характеристики светочувствительных пигментов человеческого глаза), CMY (Cyan, Magenta, Yellow - голубой, пурпурный, желтый, дополнительные к RGB) и CMYG - те же цвета, но с добавлением градаций серого. Цветовая модель RGB используется в цветных кинескопах и видеоадаптерах, CMYG - в цветной полиграфии.

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

При наиболее распространенном способе кодирования звуковой информации амплитуда сигнала измеряется через равные промежутки времени и записываются полученные значения. Например, последовательность 0, 1.5, 2.0, 1.5, 2.0, 3.0, 4.0, 3.0, 0 описывает волну звука, амплитуда которой сначала увеличивается, затем немного уменьшается, затем снова повышается и, наконец, падает до 0 (см.рис.6). Этот способ кодирования, в котором частота дискретизации составляет 8000 отсчетов в секунду, используется не первый год в дальней телефонной связи. Голос на одном конце канала кодировался в виде числовых значений, отражавших амплитуду звукового сигнала, восемь тысяч раз в секунду. Эти значения затем передавались по каналам связи и использовались для воспроизведения звука.

Рисунок 6– Звуковой сигнал, представленный последовательностью 0, 1.5,  2.0, 1.5, 2.0, 3.0, 4.0, 3.0, 0

Частота дискретизации –частота взятия отсчетов непрерывного во времени сигнала при его дискретизации.

Квантование-разбиение диапазона значений некоторой величины на конечное число интервалов.

Может показаться, что 8000 отсчетов в секунду — это большая частота дискретизации, но она все же недостаточна для высокой точности воспроизведения музыки. Для получения качественного звучания на современных музыкальных компакт-дисках используется частота дискретизации, равная 44 100 отсчетов в секунду. Для данных, полученных при каждом отсчете, отводится 16 битов памяти (или 32 бита для стереозаписей). Следовательно, для хранения одной секунды звучания требуется более миллиона битов.

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

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

Задание

1. Записать слово «stop» в двоичном  и десятичном кодах.

2. Закодировать в десятичной форме свою фамилию, используя  кодировку Windows 1251.

3. С помощью десятичных кодов зашифровано слово «info» 105 110 102 111,записать последовательность десятичных кодов для этого же слова, но записанного заглавными буквами.

4. Запишите через пробел коды букв Ф и F.

5. Сколько символов содержится в тексте, использующем таблицу ASCII, если известно, что он занимает 24 576 бит памяти?

6. Оценить информационный объем фразы, закодированной с помощью Юникода: Без труда не вытащишь и рыбку из пруда.

7.Оценить информационный объем фразы, закодированной с помощью Юникода: «Делу - время, потехе -  час».

8. Закодировать слово  – зима в десятичном и двоичном кодах.

9.  Раскодировать слово  87 79 82 76 68.

10. Закодировать слово Forest.

11. Какие символы зашифрованы кодами таблицы ASCII 82 и 143?

12. Код(номер) буквы «j» в таблице кодировки символов равен 106.Какая последовательность кодов будет соответствовать слову «file»?

13. Дан текст: «Буря мглою небо кроет». К каждому слову( в порядке следования) применены команды: выделить слово; вырезать слово. Что будет находиться в буфере обмена?

14.Выбрать фрагмент текста «2009», «2011», «файл», «file», «1b1d», имеющий минимальную сумму кодов символов( в таблице ASCII).

15.Код (номер) буквы «о» в таблице кодировки символов равен 141.Что зашифровано с помощью последовательности кодов: 144 142 141 143 145?

16.Упорядочить фрагменты текста «1xyz», «Фde», «5ы», «b2k» в порядке убывания.

17. Упорядочить фрагменты текста в порядке убывания: ДЕжЗ, 2Ежз, зДЖе, жЕдЗ.

18.Используя таблицу ASCII закодировать следующие  предложения“Мне нравится учиться в университете”.

19.C помощью кодировочной таблицы ASCII закодируйте заданный текст:I wasbornin 1975.

20. C помощью кодировочной таблицы ASCII раскодируйте заданный текст:98 121 99 107 32 105 115 32 109 121 32 100 111 103 46.

Порядок выполнения работы

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

При выполнении индивидуального задания придерживаться следующей последовательности действий:

-изучить словесную постановку задачи;

-освоить таблицы системы ASCII;

-разработать алгоритм, решающую поставленную задачу;

-написать и представить к защите отчет по работе.

Требования к отчету

Отчет должен содержать:

  1.  Цель работы.
  2.  Задание.
  3.  Таблица.
  4.  Результат выполнения задания.
  5.  Ответы на контрольные вопросы.
  6.  Выводы.

Контрольные вопросы

  1.  Что такое текст, из чего он состоит?
  2.  Перечислите кодировки текста. Перечислить достоинства и недостатки?
  3.  Дайте определение таблица кодировки?
  4.  Что такое растровое изображение, векторное и фрактальное изображение. Указать достоинства и недостатки, и какое изображение (графика) оптимальна?
  5.  Какие цветовые модели существуют и как она высчитывается?
  6.  Как кодируется звуковая информация. Что означают термины «квантование» и «частота дискретизации». Какие методы используются для обработки звука?

Лабораторная работа № 6.

Сжатие данных

Цель

Рассмотреть общие методы сжатие данных, а также познакомиться с технологиями сжатия изображения.

Задание для самостоятельной подготовки

  1.  Изучить основные методы сжатия данных[1], стр. 83-87, [2], стр.384.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

Другим методом сокращения размера данных является частотно-зависимое кодирование (frequency-dependentencoding), в котором длина кода элемента информации обратно пропорциональна частоте использования этого элемента. Эти коды являются примерами кодов переменной длины (variable-lengthcodes), что означает, что элементы информации представлены последовательностями разной длины, в отличие от таких кодов, как Unicode, в котором все символы представлены 16-битовыми последовательностями. В английском языке буквы е, t, a и i используются чаще, чем буквы z, q и х. Поэтому при кодировании текста на английском языке можно сохранить место в памяти, если использовать короткие наборы битов для первых букв и более длинные для вторых. В результате мы получим код, в котором текст будет иметь более короткое представление, чем имел бы в коде с фиксированной длиной, таком как ASCII или Unicode. Давид Хаффман известен как открыватель алгоритма, который широко используется для создания частотно-зависимых кодов. Поэтому почти все частотно-зависимые коды, используемые сегодня, — это коды Хаффмана (Huffmancodes).

Хотя мы и назвали кодирование длины серии, относительное кодирование и частотно-зависимое кодирование общими методами кодирования данных, каждое из них все-таки имеет свою область применения. В отличие от них система сжатия Лемпеля-Зива (Lempel-Zivencoding), названная в честь ее создателей Абрахама Лемпеля и Якоба Зива, является более универсальной системой. На самом деле пользователи Сети, возможно, видели или использовали обслуживающее программное обеспечение, в котором для создания сжатых файлов, называемых zip-файлами, применяется метод Лемпеля-Зива. Система кодирования Лемпеля-Зива является примером кодирования с адаптивным словарем (adaptivedictionaryencoding). Словарем в этой системе является набор стандартных блоков, из которых построено сообщение, которое нужно сжать. Если бы мы хотели сжать текст на английском языке, то такими стандартными блоками были бы буквы алфавита. Если бы мы хотели сжать уже закодированные данные, то стандартными блоками были бы цифры 0 и 1. При адаптивном кодировании словарь может изменяться в процессе кодирования. Например, в случае с английским текстом, закодировав часть сообщения, мы можем решить добавить в словарь ing и the. Теперь каждый раз, когда в тексте встретится ing или the, они могут быть закодированы при помощи обращения к словарю один раз, а не три. Метод Лемпеля-Зива позволяет разумно и эффективно адаптировать словарь в процессе кодирования (или сжатия) данных.

В растровой графике, которая производится современными цифровыми преобразователями, изображение, как правило, представляется в формате три байта на один пиксел, что приводит к большим и трудно обрабатываемым файлам растровой графики. Для того чтобы уменьшить требования к памяти, было разработано много схем сжатия. Одна их них, разработанная компанией CompuServe, называется GIF (сокращенно от GraphicInterchangeFormat — формат графического обмена). Этот стандарт сжатия решает проблему путем сокращения количества цветов, которые могут быть приписаны пикселу, до 256. Это означает, что значение каждого пиксела можно представить с помощью одного байта, а не трех. Каждому из 256 значений пиксела при помощи таблицы, которая называется палитрой, ставится в соответствие определенное сочетание красного, зеленого и синего цветов. Изменяя палитру изображения, мы можем изменять цвета изображения.

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

Другой стандарт сжатия изображений называется JPEG. Он был разработан JointPhotographicExpertsGroup (Объединенная группа экспертов в области фотографии), входящей в состав организации ISO. ФорматJPEG оказался эффективным для представления цветных фотографий. На самом деле, именно этот стандарт принят производителями современных цифровых камер, и он обещает еще долгое время иметь влияние в сфере цифровых изображений.

В действительности стандарт JPEG включает в себя несколько способов представления изображений, у каждого из которых своя задача. Например, в ситуациях, когда требуется предельная точность, формат JPEG предоставляет метод «без потерь», при котором не происходит потери информации во время кодирования изображения. В соответствии с этим алгоритмом хранится различие между соседними пикселами, а не интенсивности пикселов. Такой подход основывается на предположении, что в большинстве случаев различие между соседними пикселами можно представить более коротким двоичным кодом, чем их значение (это пример относительного кодирования). Различия записываются при помощи кода переменной длины.

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

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

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

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

BMP - bitmap - битовое отображение. Понятие "отображение" взято из математики. В математике отображение стоит очень близко к понятию функции. Для простоты считайте, что слово bitmap - это картинка (хотя это и не так).

Изображение состоит из пикселей. Формат пикселей задаётся глубиной цвета. 32-ухбитный цвет обычно состоит из четырёх каналов: альфа (прозрачность), красный, зелёный, синий: ARGB (Alpha, Red, Green, Blue). Иногда альфа-канал не используется, в этом случае изображение всё равно может занимать 32 бита, просто при вычислениях не обращают внимания на значения одного канала. В этом случае названия каналов записываются так: XRGB.

Каждый канал занимает 8 бит (1 байт) и может принимать 256 значений: от нуля до 255.

При 32-ухбитной глубине цвета каналы в bmp записываются так: BGRA. Именно в таком порядке: синий, зелёный, красный, альфа.

Размер строки данных в изображении bmp должнен быть кратен четырём (в байтах). Если это не так, то строка дополняется нулями. Это происходит если используется 1,2,4,8,16,24 бита на канал. Например, у нас есть изображение шириной в 3 пикселя и мы используем 16-битный цвет. Ширина строки: 16*3 = 48 (6 байт). Но длина строки должна быть кратной четырём, поэтому добавляются ещё два байта и длина строки в данном примере будет равна восьми байтам. Хотя в последних двух байтах каждой строки и не будет хранится полезной информации. Нужно учитывать условие кратности размера строки четырём при работе с не 32-ухбитными изображениями.

Portable Document Format (PDF) — кроссплатформенный формат электронных документов, созданный фирмой Adobe Systems с использованием ряда возможностей языка PostScript. В первую очередь предназначен для представления в электронном виде полиграфической продукции, — значительное количество современного профессионального печатного оборудования может обрабатывать PDF непосредственно. Для просмотра можно использовать официальную бесплатную программу Adobe Reader, а также программы сторонних разработчиков. Традиционным способом создания PDF-документов является виртуальный принтер, то есть документ как таковой готовится в своей специализированной программе — графической программе или текстовом редакторе

Формат PDF позволяет внедрять необходимые шрифты (построчный текст), векторные и растровые изображения, формы и мультимедиа-вставки. Поддерживает RGB, CMYK, Grayscale, Lab, Duotone, Bitmap, несколько типов сжатия растровой информации. Имеет собственные технические форматы для полиграфии: PDF/X-1, PDF/X-3. Включает механизм электронных подписей для защиты и проверки подлинности документов. В этом формате распространяется большое количество сопутствующей документации.

TIFF (TaggedImageFileFormat) — формат хранения растровых графических изображений. Изначально был разработан компанией Aldus в сотрудничестве с Microsoft для использования с PostScript. TIFF стал популярным форматом для хранения изображений с большой глубиной цвета. Он используется при сканировании, отправке факсов, распознавании текста, в полиграфии, широко поддерживается графическими приложениями. TIFF был выбран в качестве основного графического формата операционной системы NeXTStep и из неё поддержка этого формата перешла в MacOSX.

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

  •  Бинарном (двуцветном, иногда неправильно называемом чёрно-белым)
  •  Полутоновом
  •  С индексированной палитрой
  •  RGB
  •  CMYK
  •  YCbCr
  •  CIE Lab

Поддерживаются режимы 8, 16, 32 и 64 бит на канал при целочисленном, а также 32 и 64 бит на канал при представлении значения пиксела числами с плавающей запятой.

Сжатие. Имеется возможность сохранять изображение в файле формата TIFF со сжатием и без сжатия. Степени сжатия зависят от особенностей самого сохраняемого изображения, а также от используемого алгоритма. Формат TIFF позволяет использовать следующие алгоритмы сжатия:

  •  PackBits (RLE)
  •  Lempel-Ziv-Welch (LZW)
  •  LZ77
  •  ZIP
  •  JBIG
  •  JPEG
  •  CCITT Group 3, CCITT Group 4

При этом JPEG является просто инкапсуляцией формата JPEG в формат TIFF. Формат TIFF позволяет хранить изображения, сжатые по стандарту JPEG, без потерь данных (JPEG-LS).

Алгоритмы CCITT Group 3 и 4 предназначены для кодирования бинарных растровых изображений. Первоначально они были разработаны для сетей факсимильной связи (поэтому иногда их называют Fax 3, Fax 4). В настоящий момент они также используются в полиграфии, системах цифровой картографии и географических информационных системах. Алгоритм Group 3 напоминает RLE, так как кодирует линейные последовательности пикселов, а Group 4 — двумерные поля пикселов.

Формат EPS (Encapsulated PostScript) Формат Encapsulated PostScript можно назвать самым надежным и универсальным способом сохранения данных. Он использует упрощенную версию PostScript: не может содержать в одном файле более одной страницы, не сохраняет ряд установок для принтера. Как и в файлы печати PostScript, в EPS записывают конечный вариант работы, хотя такие программы, как Adobe Illustrator и Adobe Photoshop могут использовать его как рабочий. EPS предназначен для передачи векторов и растра в издательские системы, создается почти всеми программами, работающими с графикой. Использовать его имеет смысл только тогда, когда вывод осуществляется на PostScript-устройстве. EPS поддерживает все необходимые для печати цветовые модели, среди них такая, как Duotone, может записывать, так же, данные в RGB, обтравочный контур, информацию и треппинге и растрах, внедренные шрифты. В формате EPS сохраняют данные в буфере обмена (Clipboard) программы Adobe для обмена между собой.

Вместе с файлом можно сохранить эскиз (image header, preview). Это копия низкого разрешения в формате PICT, TIFF, JPEG или WMF, которая сохраняется вместе с файлом EPS и позволяет увидеть, что внутри, поскольку открыть файл на редакцию могут только Photoshop и Illustrator. Все остальные импортируют эскиз, подменяя его при печати на PostScript-принтере оригинальной информацией. На принтере, не поддерживающем PostScript, выводится на печать сам эскиз. Если вы работаете на Photoshop для Макинтош, сохраняйте эскизы в формате JPEG, остальные маковские программы сохраняют эскизы в формате PICT. Эти и JPEG-эскизы не могут использовать Windows-приложения. Если вы работаете на PC или не знаете, где будет использоваться файл, сохраняйте эскиз в формате TIFF (когда предоставляется выбор). CorelDRAW так же предлагает для эскиза векторный формат WMF, стоит очень осторожно пользоваться этим детищем Microsoft - до добра не доведет.

Изначально EPS разрабатывался как векторный формат, позднее появилась его растровая разновидность - Photoshop EPS. Кроме типа эскиза (TIFF, PICT, JPEG) Photoshop дает возможность выбрать способ кодирования данных. ASCII, Binery и JPEG.

В заключение следует заметить, что исследования в области сжатия данных представляют собой широкое поле деятельности. Мы обсудили несколько методов сжатия изображений из множества существующих. Кроме того, существуют различные техники сжатия звуковых и видеоданных. Например, группой MotionPictureExpertsGroup (MPEG — Экспертная группа по вопросам движущегося изображения), входящей в состав организации ISO, были разработаны методы, подобные тем, которые используются в стандарте JPEG, для того чтобы ввести стандарты кодирования (сжатия) движущихся изображений. Согласно этому алгоритму сначала кодируется первое изображение последовательности, подобно тому, как это делается в базисном стандарте JPEG, а затем при помощи методов относительного кодирования записываются оставшиеся изображения.

Задание

(Номер варианта соответствует вашему номеру в журнале)

  1.  Определите количество цветов в палитре при глубине цвета 4, 8, 16, 24, 32 бита.
  •  Черно-белое (без градаций серого) растровое графическое изображение имеет размер 10x10 точек. Какой объем памяти займет это изображение?
  1.  Цветное (с палитрой из 256 цветов) растровое графическое изображение имеет размер 10x10 точек. Какой объем памяти займет это изображение?
  •  В процессе преобразования растрового графического изображения количество цветов уменьшилось с 65536 до 16. Во сколько раз уменьшится объем занимаемой им памяти?
  1.  В процессе преобразования растрового графического изображения количество цветов увеличилось с 16 до 42 949 67 296. Во сколько раз увеличился объем, занимаемый им в памяти?
  •  256-цветный рисунок содержит 120 байт информации. Из скольких точек он состоит?
  1.  Для хранения изображения размером 64x32 точек выделено 64 Кбайт памяти. Определите, какое максимальное число цветов допустимо использовать в этом случае.
  •  Достаточно ли видеопамяти объемом 256 Кбайт для работы монитора в режиме 640 х 480 и палитрой из 16 цветов?
  1.  Какие графические режимы работы монитора может обеспечить видеопамять объемом в 1 Мбайт?
  •  Сканируется цветное изображение стандартного размера А4 (21x29,7 см). Разрешающая способность сканера 1200 dpi и глубина цвета 24 бита. Какой информационный объем будет иметь полученный графический файл.
  1.  Какой объем видеопамяти необходим для хранения двух страниц изображения при условии, что разрешающая способность дисплея равна 640 х 350 пикселей, а количество используемых цветов - 16?
  •  Какой объем видеопамяти необходим для хранения четырех страниц изображения, если битовая глубина равна 24, а разрешающая способность дисплея - 800 х 600 пикселей?
  1.  Объем видеопамяти равен 256 Кб, количество используемых цветов - 16. Вычислите варианты разрешающей способности дисплея при условии, что число страниц может быть равно 1, 2 или 4.
  •  Объем видеопамяти равен 1 Мб. Разрешающая способность дисплея - 800 х 600. Какое максимальное количество цветов можно использовать при условии, что видеопамять делится на две страницы?
  1.  Объем видеопамяти равен 2 Мб, битовая глубина - 24, разрешающая способность дисплея - 640 х 480. Какое максимальное количество страниц можно использовать при этих условиях?
  •  На экране дисплея необходимо отображать 224 (16777216) различных цветов. Вычислить необходимый объем одной страницы видеопамяти при различных значениях разрешающей способности дисплея (например, 640 х 480, 800 х 600, 1024 х 768, 1240 х 1024).
  1.  Битовая глубина равна 32, видеопамять делится на две страницы, разрешающая способность дисплея - 800 х 600. Вычислить объем видеопамяти.
  •  Видеопамять имеет объем, в котором может храниться 4-х цветное изображение размером 300 х 200. Какого размера изображение можно хранить в том же объеме видеопамяти, если оно будет использовать 16-цветную палитру?
  1.  Видеопамять имеет объем, в котором может храниться 4-х цветное изображение размером 640 х 480. Какого размера изображение можно хранить в том же объеме видеопамяти, если использовать 256-цветную палитру?
  •  Разрешающая способность дисплея равна 640 х 200. Для размещения одного символа в текстовом режиме используется матрица 8x8 пикселей, которая называется знакоместом. Какое максимальное количество:  1) текстовых строк,  2) знакомест в строке   может быть размещено на экране?
  1.  Для размещения одного символа в текстовом режиме используется матрица 8x8, количество текстовых строк равно 75, а знакомест в строке (см. задачу 1.170) - 100. Вычислить разрешающую способность дисплея.
  •  Битовая глубина равна 24. Сколько различных оттенков красного, зеленого и синего используется для формирования цвета?
  1.  На экране может быть отображено 256 цветов. Сколько различных уровней яркости принимает красная, зеленая и синяя составляющие?
  •  Объем видеопамяти равен 512 Кб, разрешающая способность дисплея - 320 х 200. Сколько различных уровней яркости принимает красная, зеленая и синяя составляющие при условии, что видеопамять делится на две страницы?
  1.  Битовая глубина равна 24. Сколько различных оттенков серого цвета может быть отображено на экране? Замечание. Оттенок серого цвета получается при равных значениях уровней яркости всех трех составляющих. Если все три составляющие имеют максимальный уровень яркости, то получается белый цвет; отсутствие всех трех составляющих представляет черный цвет.
  •  Битовая глубина равна 24. Опишите несколько вариантов двоичного представления светло-серых и темно-серых оттенков.
  1.  На экране компьютера необходимо получить 1024 оттенка серого цвета. Какой должна быть битовая глубина?
  •  Объем видеопамяти - 2 Мб, разрешающая способность дисплея равна 800 х 600. Сколько оттенков серого цвета можно получить на экране при условии, что видеопамять делится на две страницы?
  1.  На экране компьютера отображаются 16 цветов. Опишите двоичное представление различных оттенков зеленого и сиреневого (синий + красный) цвета.
  •  На экране компьютера отображаются 256 цветов. Опишите двоичное представление не менее пяти различных оттенков красного и желтого (красный + зеленый) цвета.
  1.  Для хранения изображения размером 128х128 точек выделено 4 Кбайт  памяти. Определите, какое максимальное число цветов в палитре
  •  16-цветный рисунок содержит 500 байт информации. Из скольких точек он состоит?
  1.  Определить требуемый объем (в мегабайтах) видеопамяти для реализации графического режима монитора с разрешающей способностью 1024×768 пикселей при количестве отображаемых цветов 4 294 967 296.
  •  Определить объем видеопамяти в Кбайтах для графического файла размером 1240х480 пикселей и глубиной цвета 16 бит
  1.  Определить объем видеопамяти в Килобайтах для графического файла размером 640х480 пикселей и палитрой из 32 цветов
  •  После преобразования графического изображения количество цветов уменьшилось с 256 до 32. Во сколько раз уменьшился объем занимаемой им памяти?
  1.  Цветной  сканер имеет разрешение 1024х512 точек на дюйм. Объем памяти, занимаемой просканированным изображением размером 2х4 дюйма, составляет около 8 Мбайт. Какова выраженная в битах глубина представления цвета сканера?
  •  Цвет пикселя, формируемого принтером, определяется тремя составляющими: голубой, пурпурной и желтой. Под каждую составляющую одного пикселя отвели по 4 бита. В какое количество цветов можно раскрасить пиксель?
  1.  Цвет пикселя монитора определяется тремя составляющими: зеленой, синей и красной. Под красную и синюю составляющие отвели по 5 бит. Сколько бит отвели под зеленую составляющую, если растровое изображение размером 8х8 пикселей занимает 128 байт?
  •  После преобразования растрового 256-цветного графического файла в черно-белый двуцветный формат его размер уменьшился на 70 байт. Каков был размер исходного файла в байтах?

Порядок выполнения работы

Определить объем изображения в формате BMP c глубиной цвета 16 бит и разрешением 160*160 пикселей.

Решение.

Размер строки при 16-битном цвете будет 16*160=2560(320 байт). 320 кратно 4, значит, добавлять байты не требуется. Тогда размер всего изображения 320*160=51200 байт=50кб.

Окончательный ответ: 50кб.

Отчет о работе

Отчет должен содержать:

  1.  Исходные данные по заданному варианту лабораторной работы.
  2.  Описания хода выполнения работы.
  3.  Результаты выполнения работы.
  4.  Ответы на контрольные вопросы.
  5.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Какие существуют общие методы сжатия данных?
  2.  Где используется сжатие данных без потерь ?
  3.  На чем основан метод относительного кодирования?
  4.  Какие основные методы сжатия изображений вы знаете?
  5.  Какая особенность человеческого глаза используется в формате JPEG?

Лабораторная работа № 7.

Архитектура ЭВМ

Цель работы

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

Задание для самостоятельной подготовки

1. Изучить теоретический материал [1], стр. 100 – 103,[2], стр.62 - 94.

2. Изучить содержание и порядок оформления лабораторной работы.

Основы теории

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

  •  системный блок;
  •  монитор;
  •  клавиатура;
  •  мышь.

Системный блок является основным узлом внутрикоторого установлены наиболее важные компоненты:

  •  материнская плата;
  •  жесткий диск;
  •  дисковод компакт – дисков;
  •  видеоадаптер (видеокарта);
  •  звуковая карта.

Материнская плата – основная плата персонального компьютера. На ней размещаются:

  •  центральный процессор (CPU — CentralProcessingUnit), или микропроцессором (часто просто процессор), для выполнения различных логических и арифметических операций без участия человека по заданной программе, которая (как и данные) хранится в памяти — чаще всего оперативной;
  •  микропроцессорный комплект (чипсет) – набор микросхем, управляющих работой внутренних устройств компьютера и определяющих основные функциональные возможности материнской платы;
  •  шины – набор проводников, по которым происходит обмен сигналами между внутренними устройствами компьютера;
  •  оперативная память (оперативное запоминающее устройство, ОЗУ) – набор микросхем, предназначенных для временного хранения данных, когда компьютер включен;
  •  постоянное запоминающее устройство (ПЗУ) – микросхема, предназначенная для длительного хранения данных , в том числе и когда компьютер выключен;
  •  разъемы для подключения дополнительных устройств (слоты).

Микропроцессор состоит из нескольких важных блоков.которые располагаются в корпусе микропроцессора. Наиболее важные из них — это устройство управления УУ, арифметически-логическое устройство АЛУ, регистры общего назначения (РОН), кэш-память первого L1 и второго L2 уровня и шины. У современных процессоров есть, разумеется, и ряд других узлов.

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

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

Шина на материнской плате компьютера и в корпусе микропроцессора — это множество плоских проводников. К шинам подключены специальные буферные микросхемы. Условно принято делить системную шину на три шины, указанные ниже.

Шина данных — двунаправленная шина, по которой данные от различных периферийных устройств подаются в процессор или, напротив, посылаются от процессора в эти устройства.

Шина адресов — однонаправленная шина, по которой от процессора посылаются сигналы, указывающие на адрес того или иного периферийного устройства.

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

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

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

Оперативная память – это массив кристаллических ячеек,способных хранить данные. С точки зрения физического принципа действия различают динамическую память (DRAM) и статическую память (SRAM).Ячейки динамической памяти можно представить в виде микроконденсаторов, способных накапливать заряд на своих обкладках. Это наиболее распространенный и экономичный вид памяти, именно поэтому он используется в качестве основной оперативной памяти компьютера.

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

Каждая ячейка памяти содержит восемь двоичных ячеек (один байт) и имеет свой адрес, который выражается числом. В большинстве современных процессоров предельный размер адреса составляет 32 разряда, следовательно, возможна непосредственная адресация к полю памяти размером 232 байт = 4 Гбайт. Количество оперативной памяти в современных компьютерах непрерывно увеличивается и в основном оно определяется требованиями операционной системы.

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

Задание

1. Изучить подключение периферийного оборудования компьютера к системному блоку.

2.Изучить компоненты системного блока.

3. Изучить компоненты материнской платы.

4. Исследовать порядок запуска компьютера.

Порядок выполнения работы

(все операции выполняются под руководством преподавателя)

I.Подключение периферийного оборудования компьютера к системному блоку

1. Убедитесь в том, что компьютер обесточен.

2. Разверните системный блок задней стенкой к себе.

3. По форме разъема клавиатуры установите форм-фактор материнской платы.

4. Установите местоположение следующих разъемов:

  •  питания системного блока;
  •  питания монитора;
  •  сигнального кабеля монитора;
  •  клавиатуры;
  •  последовательных портов;
  •  параллельных портов;
  •  наличие других портов.

5. Убедитесь в том, что все разъемы, выведенные на заднюю стенку системного блока, невзаимозаменяемые, то есть каждое периферийное устройство подключается единственным способом.

6. У звуковой карты установите местоположение следующих разъемов:

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

7. Изучите способ подключения мыши к системному блоку (PS/2, USB,беспроводная).

II. Компоненты системного блока

1. Установите местоположение системного блока.

2. Установите местоположение материнской платы.

3. Установите характер подключения материнской платы к блоку питания.

4. Установите местоположения жесткого диска и его разъема питания. Проследите направление шлейфа проводников, связывающего жесткий диск с материнской платой. Обратите внимание на местоположение проводника красного цвета – он должен быть расположен рядом с разъемом питания.

5. Установите местоположение дисковода CD (DVD). Проследите направление их шлейфов проводников и обратите внимание на местоположение проводника красного цвета относительно разъема питания.

6. Установите местоположение звуковой карты и платы видеоадаптера.

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

III. Компоненты материнской платы

1. Установите местоположение процессора и изучите организацию его системы охлаждения. По маркировке определите тип процессора и фирму – изготовителя.

2. Установите местоположение разъемов для установки модулей оперативной памяти. Выясните их количество, тип используемых модулей и суммарный объем памяти.

3. Установите местоположение слотов для установки плат расширения. Выясните их количество и тип. Зафиксируйте их различия по форме и цвету.

4. Установите местоположение микросхемы ПЗУ. По наклейке на ней определите производителя системы BIOS.

5. Установите местоположение микросхем системного комплекта (чипсета). По маркировке определите тип комплекта и фирму – изготовитель.

6. Заполните отчетные таблицы:

Разъем шины

Цвет

Размер

Устройство

Изготовитель

Модель

Процессор

Системы BIOS

Чипсет

Размеры модулей оперативной памяти

Слоты для установки плат расширения

Тип

Количество

Тип

Количество

IV. Порядок запуска компьютера

1. Включить компьютер.

2. При подаче питания на процессор происходит его обращение к микросхеме ПЗУ и запуск программы, инициализирующей работу компьютера. В этот момент на экране монитора наблюдается сообщение о версии BIOS.

3. Для наблюдения сообщений, поступающих от компьютера в процессе запуска, используется клавишаPause/Break. Для продолжения запуска используется клавиша Enter.

4. Процедура инициализации запускает процедуруPOST, выполняющую самотестирование базовых устройств. В этот момент на экране наблюдается сообщение MemoryTest и указание объема проверенной памяти компьютера.

5. При отсутствии дефектов в оперативной памяти или в клавиатуре происходит обращение к микросхеме CMOS, в которой записаны данные, определяющие состав компьютерной системы и ее настройки. На экране монитора эти данные отображаются в таблице SystemConfiguration. Приостановив запуск компьютера с помощью клавишиPause/Break, изучите таблицу и установите:

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

Продолжите запуск клавишей Enter.

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

7. Дождавшись окончания запуска операционной системы, с разрешения преподавателявыключите компьютер.

Требования к отчету

Отчёт должен содержать:

1. Тему и цель работы.

2. Краткое содержание хода выполнения работы.

3. Ответы на контрольные вопросы.

4. Выводы о проделанной работе.

Контрольные вопросы

1.Что включают в себя базовые аппаратные конфигурацииперсонального компьютера и системного блока?

2. Укажите состав и характеристики периферийных устройств

3. Какие системы расположены на материнской плате? Основные характеристики оперативной памяти.

4. Укажите основные характеристики процессора.

5. Каково назначение и основные характеристики микросхемы ПЗУ и системы BIOS?

6. Каково назначение и основные характеристики энергонезависимой памятиCMOS и чипсета?

Лабораторная работа №8

Машинный язык

Цель работы

Изучить основы машинного языка, используемого в современных ЭВМ

Задание для самостоятельной подготовки

1. Изучить теоретические основы машинного языка.[1], стр.103-109.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Первым шагом на пути к облегчению задачи программирования был отказ от использования цифр для записи команд и операндов непосредственно в той форме, в которой они используются в машине. С этой целью при разработке программ стали широко применять мнемоническую запись различных команд вместо их шестнадцатеричного представления. Например, вместо цифрового кода команды загрузки регистра программист мог теперь написать LD (от Load), а вместо кода команды копирования содержимого регистра в память мог использовать мнемоническое обозначение ST (от Story). Для записи операндов были разработаны правила, в соответствии с которыми программист мог присваивать некоторым областям памяти описательные имена (идентификаторы)и использовать их при записи команд программы вместо адресов соответствующих ячеек памяти. Одним из специфических вариантов является присвоение мнемонических имен регистрам центрального процессора, например R0, R1, R2,...

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

Вначале программисты использовали такие обозначения при разработке программ на бумаге, а затем переводили их на машинный язык. Однако вскоре стало понятно, что такой перевод может выполнить и сама машина. В результате были разработаны программы, названные ассемблерами и предназначенные для перевода записанных в мнемоническом виде программ на машинный язык. Название ассемблер (assembler — сборщик) эти программы получили потому, что их назначение заключалось в сборке машинных команд из кодов команд и операндов, полученных в результате перевода мнемонических обозначений и идентификаторов. Мнемонические системы записи программ стали, в свою очередь, рассматриваться как особые языки программирования, именуемые языками ассемблера.

Кодированное представление машинной команды обычно состоит из двух частей: поля кода операции (op-codefield – сокращение от operationcodefield) и поля операнда (operandfield). Битовая комбинация, расположенная в поле кода операции, обозначает, какая из элементарных операций, таких как операции сохранения, сдвига, XOR или перехода, запрашивается командой. Набор битов, находящийся в поле операнда, содержит подробные сведения об объектах, участвующих в операции, определенной кодом операции. Например, в случае команды сохранения в поле операнда содержится информация о том, в каком регистре находятся данные, которые нужно сохранить, и какая ячейка памяти должна получить эти данные. Структура машинной команды представлена на рисунке 1.

Рисунок 1 -  Структура машинной команды

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

Примем, что гипотетическая ВМ имеет следующие особенности:

Одноадресныекоманды. Адресная часть команды (АЧ) содержит только один адрес. При выполнении операций с двумя операндами предполагается, что операнд, адрес которого в команде не указан, находится в специальном регистре АЛУ — аккумуляторе, а также, что результат остается в аккумуляторе.

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

На функциональной схеме показаны типовые узлы гипотетической ВМ,

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

Рисунок 2 – Функциональная схема гипотетической фон-Неймановской ВМ

Задания

Задание 1. В соответствии с номером варианта:

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

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

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

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

5. Написать последовательность машинных команд для логического умножения числа из основной памяти и результата операции его циклического сдвига вправо на 3 позиции.

6. Описать действия, закодированные в машинных командах: 18A3, 5056, 306E, 95F3, 8085.

7. Написать последовательность машинных команд для выполнения логического умножения (AND) двух чисел, хранящихся в основной памяти.

8. Описать действия, закодированные в машинных командах: 108D, 11B3, 30B3, 3180, B114.

9. Описать действия, выполняемые последовательностью машинных команд: 1105, 1206, 5312, A302, 3307,  С000.

10. Описать действия, закодированные в машинных командах: 407E, 2835, 9028, A302, B3AD.

11. Написать последовательность машинных команд для выполнения поразрядной логической операции XOR над числом 45 и результатом логического сложения двух чисел из основной памяти.

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

13. Описать действия, закодированные в машинных командах: 2345, 4035, 6712, A303, 37A1.

14. Написать последовательность машинных команд для выполнения поразрядной операции XOR над числами, хранящимися в основной памяти компьютера.

15. Описать действия, выполняемые последовательностью машинных команд: 1404, 1505, 7645, B6A1, 9645.

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

17. Описать последовательность действий, закодированных в машинных командах: 1101, 1202, 5312, 3303, C000.

18. Описать действия, закодированные в машинных командах: 7CB4, 40A4, 634E, 203A, A403.

19. Описать действия, закодированные в машинных командах: 1183, 30B3, 108B, 3180, B119.

20. Написать последовательность машинных команд для выполнения логического сложения (OR) двух чисел, хранящихся в основной памяти.

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

Порядок выполнения работы

1. Выбрать первое слагаемое из основной памяти и поместить его в регистр.

2. Выбрать второе слагаемое из основной памяти и поместить его в другой регистр.

3. Активировать сумматор, указав используемые на этапах 1 и 2 регистры в качестве входных и задав еще один регистр в качестве выходного.

4. Сохранить результат выполнения операции в основной памяти.

5. Завершить выполнение операции.

Пример выполнения программы

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

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

Рисунок 3 – Программа, хранящаяся в памяти и готовая к выполнению

Устройство управления начинает шаг выбора машинного цикла, извлекая команду из ячейки памяти с адресом А0 и помещая эту команду (156С) в регистр команд (Рисунок 4, а). Обратите внимание на то, что в нашей машине команда имеет длину 16 битов (2 байта), поэтому выбранная команда размещается в ячейках памяти с адресами А0 и А1. Устройство управления учитывает этот факт извлекает содержимое обеих ячеек и помещает этот код в регистр команд, который имеет длину, равную 16 битам. Затем устройство управления добавляет значение 2 к счетчику команд, чтобы он содержал адрес следующей команды (Рисунок 4, б). В конце шага выбора первого машинного цикла счетчик команд и регистр команд содержат следующие данные: счетчик команд - А2, регистр команд — 156С.

Затем устройство управления анализирует команду, находящуюся в регистре команд, и делает вывод о том, что нужно загрузить содержимое ячейки памяти с адресом 6С в регистр 5. Это действие осуществляется в процессе шага выполнения.третьего шага машинного цикла. Затем устройство управления начинает следующий цикл.

Новый цикл начинается с выбора команды 166Dиз ячеек памяти начиная с адреса А2. Устройство управления помещает эту команду в регистр команд и увеличивает счетчик команд до значения А4. Следовательно, теперь значения в счетчике команд и в регистре команд таковы: счетчик команд — А4, регистр команд — 166D.

Рисунок 4 – Выполнение шага выбора машинного цикла: а – в начале шага выбора извлекается команда, находящаяся по адресу А0, и помещается в регистр команд; б – затем к счетчику команд добавляется приращение, чтобы он указывал на следующую команду

Теперь устройство управления расшифровывает команду 166Dи определяет, что нужно загрузить содержимое ячейки память с адресом 60 в регистр 6. Затем выполняет команду, в результате чего регистр 6 загружается.

Поскольку счетчик команд содержит значение А4, устройство управления извлекает следующую команду, начиная с этого адреса. В результате команда 5056 помещается в регистр команд, а счетчик команд увеличивается до А6. Теперь устройство управления расшифровывает содержимое регистра команд и выполняет то, что предписывает команда, активируя схему сложения в дополнительном коде, на входе которой находятся регистры 5 и 6.

Во время шага выполнения арифметико-логическое устройство находит сумму, помещает результат в регистр 0 и докладывает устройству управления о том, что операция завершена. После чего устройство управления начинает другой машинный цикл. И опять, с помощью счетчика команд оно извлекает следующую команду (306Е) из двух ячеек памяти начиная с адреса А6 и увеличивает счетчик команд до значения А8. Полученная команда затем расшифровывается и выполняется. На данном этапе сумма помещается в ячейку памяти с адресом 6Е.

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

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

Требования к отчету

Отчет должен содержать

  1.  Тему и цель работы
  2.  Исходные данные по заданному варианту лабораторной работы;
  3.  Описание хода выполнения работы;
  4.  Результат выполнения работы;
  5.  Ответы на контрольные вопросы;
  6.  Выводы о проделанной роботе.

Контрольные вопросы

  1.  Почему глагол «перемещать» не точно отражает сущность операции перемещения данных из одной части компьютера в другую?
  2.  В команде перехода, о которой рассказывалось в разделе, пункт назначения был определен в самой команде (например, «перейти к шагу 6»). Недостаток такого описания состоит в том, что если впоследствии имя (номер) команды изменится, нам придется изменить ее имя во всех переходах, которые на нее ссылаются. Опишите другой способ записи команды перехода, при котором пункт назначения не задается явно.
  3.  Условным или безусловным переходом является инструкция «если 0 равен 0. тогда перейти к шагу 7». Поясните свой ответ.
  4.  Что обозначают следующие команды, написанные на машинном языке
    1.  368А; 2) BADE; 3) 8G3C; 4) 40F4.
  5.  В чем состоит различие между командами 15АВ и 25АВ?
  6.  Ниже приведены описания команд, запишите их на машинном языке
  7.  Загрузить в регистр 3 шестнадцатеричное значение 56.
  8.  Выполнить циклический сдвиг регистра 5 на три бита вправо.
  9.  Выполнить операцию ANDнад содержимым регистра А и регистра 5и сохранить результат в регистре 0.

Лабораторная работа № 9.

Машинные команды

Цель работы

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

Задание для самостоятельной подготовки

  1.  Изучить состав и содержание основных машинных команд [1], стр. 103-120.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Машинная команда представляет собой закодированное по определенным правилам указание микропроцессору на выполнение некоторой операции или действия. Машинная команда выполняется процессором автоматически и не требует каких-либо дополнительных указаний и пояснений. Показанная на рис. 1 последовательность этапов представляет собой пример незакодированных машинных команд.

Рисунок 1 - Пример незакодированных машинных команд

Кодированное представление машинной команды обычно состоит из двух частей: поля кода операции (op-codefield – сокращение от operationcodefield) и поля операнда (operandfield). Битовая комбинация, расположенная в поле кода операции, обозначает, какая из элементарных операций, таких как операции сохранения, сдвига, XOR или перехода, запрашивается командой. Набор битов, находящийся в поле операнда, содержит подробные сведения об объектах, участвующих в операции, определенной кодом операции. Например, в случае команды сохранения в поле операнда содержится информация о том, в каком регистре находятся данные, которые нужно сохранить, и какая ячейка памяти должна получить эти данные. Структура машинной команды представлена на рис. 2.

Рисунок 2 - Структура машинной команды

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

Различают два подхода к тому, каким должен быть центральный процессор. При первом подходе считается, что центральный процессор должен выполнять минимальный набор машинных команд. Результатом такого подхода является вычислительная машина с сокращенным набором команд (ReducedInstructionSetComputer — RISC-машина). В защиту RISC-процессора приводится аргумент, что такой процессор является эффективным и быстродействующим. В то же время, есть сторонники центрального процессора, способного выполнять большое количество сложных команд, даже если многие из них избыточны. Результатом этого подхода является вычислительная машина со сложным набором команд (ComplexInstructionSetComputer — CISC-машина). В защиту CISC-архитектуры приводят аргумент, что более сложный процессор легче программировать, так как можно обойтись одной командой для выполнения задачи, которая в RISC-процессоре потребовала бы длинной последовательности команд.Для простоты изложения мы будем рассматривать RISC-процессор.

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

Команды передачи данных включают те команды, при выполнении которых происходит перемещение данных из одного места в другое. Действия, выполняемые на этапах 1, 2 и 4 на рис. 1,относятся к этой категории. Как и в случае с основной памятью, наиболее типичной является ситуация, когда перемещаемые данные сохраняются и в месте их исходного расположения. Процедура выполнения команд передачи данных больше напоминает копирование информации с одного места в другое, а не обычное их перемещение. Поэтому чаще всего употребляемые названия команд пересылка (transfer) или перемещение (move) следует считать выбранными неверно. Более подходящими названиями для этих команд можно считать копирование (copy) или дублирование (clone).

Поскольку мы коснулись терминологии, то следует упомянуть, что для передачи данных между центральным процессором и основной памятью существуют специальные термины. Требование заполнить регистр общего назначения содержимым ячейки памяти обычно называется командой загрузки (load), и наоборот, требование переместить содержимое регистра в ячейкуосновной памяти называется командой сохранения(store). Этапы 1 и 2 на рис.1 являются командами загрузки, а этап 4 — командой сохранения.

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

К арифметическим и логическим командам относятся те команды, которые указывают блоку управления на необходимость запросить выполнение определенных действий арифметико-логического блока. На рис. 1 к этой категории относятся действия, выполняемые на этапе 3. Как следует из самого названия арифметико-логического блока, он также предусматривает выполнение группы операций, отличающихся от основных арифметических действий. К ним относятся обычные логические операции AND, OR и XOR. Эти операции часто используются для того, чтобы манипулировать отдельными битами регистра, не затрагивая остальных.

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

Команды управления. В эту группу входят команды, предназначенные для управления ходом выполнения программы, а не обработки каких-либо данных. На рис. 1 к этой категории относятся действия, выполняемые на этапе 5, хотя это очень простой пример. Эта группа включает наиболее интересные машинные команды, такие как команды перехода (jump) или ветвления (branch).Они используются для перенаправления управляющего блока на выполнение команды, отличной от той, которая является очередной в выполняемой последовательности. Команды перехода разделяются на команды безусловного и условного перехода. Примером первых может быть инструкция «перейти к этапу 5», примером второй — «если полученное значение равно 0, тогда перейти к этапу 5». Различие заключается в том, что условный переход осуществляется только тогда, когда выполняется условие. В качестве примера можно привести последовательность команд, представленную на рис. 3, которая является реализацией алгоритма деления двух чисел. В этом примере этап 3 содержит команду условного перехода, предназначенную для предотвращения операции деления на нуль.

Рисунок 3 - Алгоритм деления двух чисел, сохраняемых в основной памяти

Задание

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

Код

оператора

Операнд

Описание

1

RXY

Загрузить в регистр R битовую комбинацию из ячейки памяти по адресу XY.

2

RXY

Загрузить в регистр R битовую комбинацию XY.

3

RXY

Записать битовую комбинацию из регистра R в ячейку памяти по адресу XY.

4

0RS

Поместить битовую комбинацию из регистра R в регистр S.

5

RST

Сложить битовые комбинации в регистрах S и T как числа, представленные в двоичном дополнительном коде, и поместить результат в регистр R.

6

RST

Сложить битовые комбинации в регистрах S и T как значения с плавающей точкой и поместить результат (число с плавающей точкой) в регистр R.

7

RST

Применить логическую операцию OR к битовым комбинациям в регистрах S и T поместить результат в регистр R.

8

RST

Применить логическую операцию AND к битовым комбинациям в регистрах S и T и поместить результат в регистр R.

9

RST

Применить логическую операцию XOR к битовым комбинациям в регистрах S и T и поместить результат в регистр R.

A

R0X

Циклически сдвинуть битовую комбинацию в регистре R на один бит вправо X раз. При каждом сдвиге поместить крайний левый младший бит на место крайнего правого старшего бита.

B

RXY

Перейти к команде, записанной в ячейку памяти по адресу XY, если битовая комбинация в регистре R равна битовой комбинации в регистре 0. Иначе продолжить последовательное выполнение команд.

C

000

Остановка программы.

Задание

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

2.Написать последовательность машинных команд для выполнения поразрядной операции XOR над числами, хранящимися в основной памяти компьютера.

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

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

5.Описать последовательность действий, закодированных в машинных командах: 1101, 1202, 5312, 3303, C000.

6.Написать последовательность машинных команд для выполнения логического сложения (OR) двух чисел, хранящихся в основной памяти.

7.Описать действия, закодированные в машинных командах: 407E, 2835, 9028, A302, B3AD.

8.Описать действия, закодированные в машинных командах: 108D, 11B3, 30B3, 3180, B114.

9.Описать действия, выполняемые последовательностью машинных команд: 1105, 1206, 5312, A302, 3307,  С000.

10.Написать последовательность машинных команд для выполнения логического умножения (AND) двух чисел, хранящихся в основной памяти.

11.Написать последовательность машинных команд для выполнения поразрядной логической операции XOR над числом 45 и результатом логического сложения двух чисел из основной памяти.

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

13.Описать действия, закодированные в машинных командах: 2345, 4035, 6712, A303, 37A1.

14.Описать действия, закодированные в машинных командах: 1183, 30B3, 108B, 3180, B119.

15.Описать действия, выполняемые последовательностью машинных команд: 1404, 1505, 7645, B6A1, 9645.

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

17.Написать последовательность машинных команд для логического умножения числа из основной памяти и результата операции его циклического сдвига вправо на 3 позиции.

18.Описать действия, закодированные в машинных командах: 7CB4, 40A4, 634E, 203A, A403.

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

20.Описать действия, закодированные в машинных командах: 14A3, 5056, 306E, 95F3, 8045.

Порядоквыполненияработы

(на примере)

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

Решение.Для того чтобы сложить эти два числа, их надо предварительно загрузить в регистры. Число 36 можно загрузить в регистр командой 2136. Предположим, что требуемое число в основной памяти хранится в ячейке с адресом 01, тогда загрузить его можно с помощью команды 1201. Теперь для сложения этих чисел можно воспользоваться командой 5312. Результат сохраним в основной памяти командой 3302 и завершим последовательность командой останова C000.

Окончательный ответ: 2136, 1201, 5312, 3302, С000.

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы
  2.  Задание и исходные данные по заданному варианту работы.
  3.  Последовательность и обоснование шагов по выполнению задания.
  4.  Окончательный ответ.
  5.  Ответы на контрольные вопросы
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что такоемашинная команда? Приведите примеры машинных команд.
  2.  На какие категории можно разделить машинные команды?
  3.  Из каких частей состоит закодированная машинная команда?
  4.  Какие команды относятся к командам управления? Для чего они нужны?

Лабораторная работа № 10

Обработка данных

Цель

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

Задание для самостоятельной подготовки

  1.  Изучить основные понятия, связанные с обработкой данных [1], стр. 68-73. а также возможности программы Microsoft Excel, [2], стр..
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

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

проведения однотипных расчетов над большими наборами данных;

автоматизации итоговых вычислений;

решения задач путем подбора значений параметров, табулирования формул;

обработки результатов экспериментов;

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

подготовки табличных документов;

построения диаграмм и графиков по имеющимся данным.

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

Документ Excelназываетсярабочей книгой. Рабочая книга представляет собой наборрабочих листов, каждый из которых имеет табличную структуру и может содержатьодну или несколько таблиц. В окне документа в программе Excelотображается толькотекущий рабочий лист, с которым и ведется работа . Каждый рабочийлист имеет название, которое отображается на ярлычке листа, отображаемом в егонижней части. С помощью ярлычков можно переключаться к другим рабочим листам, входящим в ту же самую рабочую книгу. Чтобы переименовать рабочий лист,надо дважды щелкнуть на его ярлычке.

Рабочий лист состоит из строк и столбцов. Столбцы озаглавлены прописнымилатинскими буквами и, далее, двухбуквенными комбинациями. Всего рабочий листможет содержать до 256 столбцов, пронумерованных отА до IV. Строки последовательно нумеруются цифрами, от 1 до 65 536 (максимально допустимый номерстроки).

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

Задание

Задание 1. Найти решения уравнений.

  1.  x – 0,2sin (x + 0,5) = 0
  2.  x2 – lg (x + 2) = 0
  3.  x3 + 25x + 19 = 0
  4.  x2 – 20sin x = 0
  5.  ln x + (x + 1)3 = 0
  6.  x4 – 2x3 – 5x2 – 10x = 0
  7.  x2 – sin 5x = 0
  8.  ex + x2 = 2
  9.  x3 – 18x + 33 = 0
  10.  1,8x2 – sin 10x = 0
  11.  2 ln x – 1/x = 0
  12.  x4 – 4x3 – 19x2 – 26x + 1 = 0
  13.   – 1/x = 0
  14.  x ln x – 100 = 0
  15.  x3 – 21x – 47 = 0
  16.  e-x + x2 = 0
  17.  x3 + 35x – 12 = 0
  18.  x2 – cos x2 = 6
  19.  (x – 1)2 – 0,5ex = 0
  20.  x4 – 8x3 – 10x2 – 40x + 7 = 0

Задание 2. Решить задачу оптимизации.

Задача. Завод производит электронные приборы трех видов (прибор А, прибор В и прибор С), используя при сборке микросхемы трех типов (тип 1, тип 2 и тип 3). Расход микросхем задается следующей таблицей:

Вариант

Микросхемы

Прибор А

Прибор В

Прибор С

1

Тип 1

1

2

2

Тип 2

1

2

1

Тип 3

4

2

3

2

Тип 1

1

2

2

Тип 2

2

1

2

Тип 3

3

3

2

3

Тип 1

1

1

1

Тип 2

3

4

4

Тип 3

2

1

1

4

Тип 1

1

1

1

Тип 2

4

3

3

Тип 3

1

2

2

5

Тип 1

2

1

1

Тип 2

1

2

2

Тип 3

3

3

3

6

Тип 1

2

1

1

Тип 2

2

1

1

Тип 3

2

4

4

7

Тип 1

2

5

1

Тип 2

3

0

3

Тип 3

1

1

2

8

Тип 1

3

2

2

Тип 2

1

1

2

Тип 3

2

3

2

9

Тип 1

3

2

2

Тип 2

2

2

1

Тип 3

1

2

3

10

Тип 1

3

1

1

Тип 2

3

4

4

Тип 3

0

1

1

11

Тип 1

4

1

1

Тип 2

1

3

3

Тип 3

1

2

2

12

Тип 1

4

1

1

Тип 2

2

2

2

Тип 3

0

3

3

13

Тип 1

0

1

1

Тип 2

1

1

4

Тип 3

5

4

1

14

Тип 1

0

1

1

Тип 2

2

3

1

Тип 3

4

2

4

15

Тип 1

0

1

1

Тип 2

3

2

2

Тип 3

3

3

3

16

Тип 1

0

1

1

Тип 2

4

1

3

Тип 3

2

1

2

17

Тип 1

0

5

1

Тип 2

5

0

4

Тип 3

1

1

1

18

Тип 1

1

5

3

Тип 2

0

0

1

Тип 3

5

1

2

19

Тип 1

2

5

3

Тип 2

0

0

2

Тип 3

4

1

1

20

Тип 1

3

5

3

Тип 2

0

0

3

Тип 3

3

1

0

Стоимость изготовленных приборов одинакова.

Ежедневно на склад завода поступает 400 микросхем типа 1 и по 500 микросхем типов 2 и 3. Каково оптимальное соотношение дневного производства приборов различного типа, если производственные мощности завода позволяют использовать запас поступивших микросхем полностью?

Порядок выполнения работы

Пример 1. Решение уравнений средствами программы Excel

Задача. Найти решение уравнения х3 - Зх2 + х = -1.

  1.  Запустите программу Excel(Пуск ► Программы ► MicrosoftExcel).
  2.  Создайте новую рабочую книгу (кнопка Создать на стандартной панели инструментов).
  3.  .Создайте новый рабочий лист (Вставка ► Лист), дважды щелкните на его ярлычке и присвойте ему имя Уравнение.
  4.  Занесите в ячейку А1 значение 0.
  5.  Занесите в ячейку В1 левую часть уравнения, используя в качестве независимой переменной ссылку на ячейку А1. Соответствующая формула может, например, иметь вид =А1^3-3*А1^2+А1.
  6.  Дайте команду Сервис ► Подбор параметра.
  7.  В поле Установить в ячейке укажите В1, в поле Значение задайте -1, в поле Изменяя значение ячейки укажите А1.
  8.  Щелкните на кнопке ОК и посмотрите на результат подбора, отображаемый в диалоговом окне Результат подбора параметра. Щелкните на кнопке ОК, чтобы сохранить полученные значения ячеек, участвовавших в операции.
  9.  Повторите расчет, задавая в ячейке А1 другие начальные значения, например 0,5 или 2. Совпали ли результаты вычислений? Чем можно объяснить различия?
  10.  Сохраните рабочую книгу book.xls.

Пример2. Решение задач оптимизации средствами программы Excel

Задача. Завод производит электронные приборы трех видов (прибор А, прибор В и прибор С), используя при сборке микросхемы трех типов (тип 1, тип 2 и тип 3). Расход микросхем задается следующей таблицей:

Микросхемы

Прибор А

Прибор В

Прибор С

Тип 1

2

5

1

Тип 2

2

0

4

Тип 3

2

1

1

Стоимость изготовленных приборов одинакова.

Ежедневно на склад завода поступает 400 микросхем типа 1 и по 500 микросхем типов 2 и 3. Каково оптимальное соотношение дневного производства приборов различного типа, если производственные мощности завода позволяют использовать запас поступивших микросхем полностью?

  1.  Запустите программуExcel(Пуск ► Программы ► MicrosoftExcel) и откройте рабочую книгу book.xls, созданную ранее.
  2.  Создайте новый рабочий лист (Вставка ► Лист), дважды щелкните на его ярлычке и присвойте ему имя Организация производства.
  3.  В ячейки А2, A3 и А4 занесите дневной запас комплектующих — числа 400, 500 и 500 соответственно.
  4.  В ячейки С1, D1 и Е1 занесите нули — в дальнейшем значения этих ячеек будут подобраны автоматически.
  5.  В ячейках диапазона С2:Е4разместите таблицу расхода комплектующих.
  6.  В ячейках В2:В4 нужно указать формулы для расчета расхода комплектующих по типам. В ячейке В2 формула будет иметь вид =$C$1*C2+$D$1*D2+$E$1*E2,а остальные формулы можно получить методом автозаполнения (обратите внимание на использование абсолютных и относительных ссылок).
  7.  В ячейку F1 занесите формулу, вычисляющую общее число произведенны}приборов: для этого выделите диапазон С1 :Е1 и щелкните на кнопке Автосуммана стандартной панели инструментов.
  8.  Дайте команду Сервис ► Solver (Поиск решения) — откроется диалоговое окне SolverParameters (Поиск решения).
  9.  В поле SetTargetCell (Установить целевую) укажите ячейку, содержащую оптимизируемое значение (F1). Установите переключатель EqualToМах (Равноемаксимальному значению) (требуется максимальный объем производства).
  10.  В поле ByChangingCells (Изменяя ячейки) задайте диапазон подбираемых параметров — С1:Е1.
  11.  Чтобы определить набор ограничений, щелкните на кнопке Add (Добавить). В диалоговом окне AddConstraint (Добавление ограничения) в поле CellReference (Ссылка на ячейку) укажите диапазон В2:В4. В качестве условия задайте <=. В поле Constraint (Ограничение) задайте диапазон А2:А4. Это условие указываетчто дневной расход комплектующих не должен превосходить запасов. Щелкните на кнопке ОК.
  12.  Снова щелкните на кнопке Add (Добавить). В поле CellReference (Ссылка на ячейку) укажите диапазон С1:Е1. В качестве условия задайте >=. В поле Constraint (Ограничение) задайте число 0. Это условие указывает, что число производимых приборов неотрицательно. Щелкните на кнопке ОК.
  13.  Снова щелкните на кнопке Add (Добавить). CellReference (Ссылка на ячейку) укажите диапазон С1 :Е1. В качестве условия выберите пункт int (цел). Это условие не позволяет производить доли приборов. Щелкните на кнопке ОК.
  14.  Щелкните на кнопке Solve (Выполнить). По завершении оптимизации откроется диалоговое окно SolverResults (Результаты поиска решения).
  15.  Установите переключатель KeepSolverSolution (Сохранить найденное решение), после чего щелкните на кнопке ОК.
  16.  Проанализируйте полученное решение. Кажется ли оно очевидным? Проверьте его оптимальность, экспериментируя со значениями ячеек С1:Е1. Чтобы восстановить оптимальные значения, можно в любой момент повторить операцию поиска решения.
  17.  Сохраните рабочую книгу book.xls.

Отчет о работе

Отчет должен содержать:

  1.  Исходные данные по заданным вариантам лабораторной работы.
  2.  Описания хода выполнения работы.
  3.  Результаты выполнения работы.
  4.  Ответы на контрольные вопросы.
  5.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Поясните содержание термина «обработка информации»?
  2.  Какие существуют виды обработки информации?
  3.  Какие существуют процедуры обработки информации?
  4.  С какой целью производится обработка информации?
  5.  Каковы основные функциональные возможности программы MicrosoftExcel?

Лабораторная работа № 11.

Настройка среды операционной системы

Цель работы

Формирование навыков настройки среды операционной системы

Задание для самостоятельной подготовки

  1.  Изучитьархитектуру операционной системы [1], стр. 139-151, [2], стр.116-139.
  2.  Изучить содержание и порядок оформления лабораторной работы

Основы теории

Главное меню системы Windows, которое называется "Меню Пуск" - это основное связующие звено с программами, папками и параметрами компьютера, запускаемое по нажатию на кнопку "Пуск" или с помощью клавиши с эмблемой Windows на клавиатуре. По умолчанию на панели задач эта кнопка располагается в левом углу. Меню "Пуск" впервые появилось в операционной системе Windows 95. В системе Windows 2000 "Классическое" меню "Пуск" было незначительно усовершенствовано. Начиная с Windows XP, у меню "Пуск" появилось два варианта: "Классический", интерфейс которого практически не изменился со времени Windows 2000 и "Стандартный", который имеет более дружественный интерфейс и установлен по умолчанию. Меню "Пуск" операционной системы Windows Vista было существенно переработано. В нем был изменен доступ к часто используемым программам и специальным папкам, отображение аватара пользователя, кнопка выключения компьютера и многое другое. В операционной системе Windows 7 "Стандартный" интерфейс меню "Пуск" незначительно изменился по сравнения с системой-предшественницей, но классический вариант оформления этого меню был исключен. В данном руководстве речь пойдет о компонентах меню "Пуск" и о его настройке.После нажатия на кнопку "Меню Пуск" на панели задач, или клавишу Windows на клавиатуре откроется меню "Пуск", которое отображено на рисунке 1:

Рисунок 1 – Меню Пуск

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

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

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

В операционной системе Windows 7 существует около 30 разнообразных настроек, связанных с меню "Пуск". В этой работе будут рассмотрены все возможные настройки этого меню.

Действия кнопки питания

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

1. Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск".

2. Перейдите на вкладку "Меню "Пуск"".

3. В раскрывающемся списке "Действия кнопки питания" выберите нужное для вас действие.

Удалить "Выйти из системы" из меню "Пуск"

Из меню "Пуск" можно удалить отдельно только пункт "Выйти из системы". Этот параметр влияет только на вид меню "Пуск" и не исключает отображение команды "Завершение сеанса" в диалоговом окне "Безопасность Windows", которое открывается при нажатии клавиш CRTL+ALT+DEL, а также использования других методов.

Снять флажок "Хранить и отображать список недавно открывавшихся

программ в меню "Пуск""

В диалоговом окне команды "Выполнить" система сохраняет все действия, которые вы вводили. Журнал недавно открывавшихся программ можно периодически очищать или просто запретить сохранение недавно открывавшихся программ. Для этого выполните следующие действия:

1. Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск".

2. Перейдите на вкладку "Меню "Пуск"".

3. В разделе "Конфиденциальность" снимите флажок с опции "Хранить и отображать список недавно открывавшихся программ в меню "Пуск"".

Снять флажок "Хранить и отображать список недавно открывавшихся элементов в меню "Пуск" и на панели задач"

Также можно очистить список недавно открывавшихся элементов в меню "Пуск" и на панели задач. Для этого выполните следующие действия:

1. Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск".

2. Перейдите на вкладку "Меню "Пуск"".

3. В разделе "Конфиденциальность" снимите флажок с опции "Хранить и отображать список недавно открывавшихся элементов в меню "Пуск" и на панели задач".

Настройка правой панели меню "Пуск"

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

1.Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск" которое изображено на Рисунке 2.

2. Перейдите на вкладку "Меню "Пуск"".

3. Нажмите на кнопку "Настроить".

4. Установите рекомендуемое действие для внешнего вида определенных элементов меню "Пуск".

Рисунок 2 – Настройка меню Пуск

Выделять недавно установленные программы.

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

1. Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск".

2. Перейдите на вкладку "Меню "Пуск"".

3. Нажмите на кнопку "Настроить".

4. Снимите флажок с опции "Выделять недавно установленные программы".

Активировать пункт "Крупные значки" из меню "Пуск"

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

Разрешить контекстные меню и перетаскивание объектов

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

Раскрывать меню при наведении и задержке указателя мыши

Изначально, как все стандартные папки меню "Пуск", так и списки переходов открываются при наведении и задержке указателя мыши. Для отключения этой опции вы можете снять флажок "Раскрывать меню при наведении и задержке указателя мыши".

Сортировать в меню "Все программы" по именам

По умолчанию, все элементы, расположенные в меню "Пуск" сортируются по именам в алфавитном порядке. Эту настройку можно отключить, используя графический интерфейс:

1. Нажмите правой кнопкой на панели задач и из контекстного меню выберите команду "Свойства" для открытия диалога свойств панели задач и меню "Пуск" которое изображено на Рисунке 2.

2. Перейдите на вкладку "Меню "Пуск"".

3. Нажмите на кнопку "Настроить".

4. Снимите флажок с опции "Сортировать меню "Все программы" по именам"

Панель управления

Следующее с чем мы должны ознакомится для выполнения лабораторной работы, это ссылка «Панель управления» в правой части меню "Пуск". Панель управления, открывает панель управления, которая позволяет настраивать внешний вид и функции компьютера, добавлять и удалять программы, устанавливать сетевые подключения и управлять учетными записями пользователей, то есть выполняет все действия,  для настройки операционной среды  которые мы и должны освоить.После открытия ссылки “ Панель управления“ откроется окно “Все элементы управления”, в котором те элементы которые нам нужны для настройки . Рисунок 3.

Рисунок 3 - Все элементы управления

Настройки экрана. Для того чтобы настроить экран нам понадобитсяв окне “Все элементы управления” выбрать раздел “Экран “ и в появившемся окне изображённом на рисунке 4 ,  выбрать пункт “Настройки параметров экрана”

                               Рисунок 4 -  Настройки экрана

И здесь мы можем выбрать разрешение или поменять монитор(современные видеокарты имеют два VGAпортов и мы можем подсоединить два монитора или монитор и прожектор и можем выбрать что нам нужно).

Настройка клавиатуры. Для настройки клавиатуры нам надо в окне “Все элементы управления” выбрать раздел “Клавиатура “.

Рисунок 5 -  Настройки клавиатуры

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

Настройки мыши.Чтобы настроить мышь нам надо выбрать раздел “Мышь” изображённый на рисунке 6. В разделе мышь есть пять пунктов. В которых находятся настройки где мы можем настроить указатель ,   его  скорость перемещения, отображение следа а также кнопки мыши, колёсико.

Рисунок 6 – Настройки мыши

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

                            Рисунок 7 – Настройка звука

Задание

  1.  Установить автоматический запуск  необходимых программ.
  2.  Произвести настройку и реорганизацию главного меню.
  3.  Произвести создание и использование меню избранного.
  4.  Осуществить настройку панели быстрого запуска.
  5.  Осуществить настройку экрана, клавиатуры, мыши и звука.

Порядок выполнения работы

1. Изучить основы теории.

2. Разобрать поэтапно и выполнить каждое действие в задании.

Требования к отчету

Отчёт должен содержать:

  1.  Тему и цель работы.
  2.  Краткое содержание проделанной работы.
  3.  Ответы на контрольные вопросы.
  4.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Какую структуру и функциональный состав имеет операционная система?
  2.  Как обеспечивается автоматический запуск операционной системы?
  3.  Как производится взаимодействие с аппаратным обеспечением?
  4.  Что находится в меню "Пуск"?
  5.  Что находиться  в “Панели управления”?

Лабораторная работа №12

Служба WorldWideWeb

Цель работы

Формирование навыков работы в сетиWorld Wide Web.

Задание для самостоятельной подготовки

  1.  Изучить основы организации сети Интернет[1], стр.160-181.
  2.  Изучить содержаниеи порядок выполнения лабораторной работы.

Основы теории

Всемирная паутина (WorldWideWeb) — распределенная система, предоставляющая доступ к связанным между собой документам, расположенным на различных компьютерах, подключенных к Интернету. Всемирную паутину образуют миллионы web-серверов. Большинство ресурсов всемирной паутины представляет собой гипертекст. Гипертекстовые документы, размещаемые во всемирной паутине, называются web-страницами. Несколько web-страниц, объединенных общей темой, дизайном, а также связанных между собой ссылками и обычно находящихся на одном и том же web-сервере, называются web-сайтом. Для загрузки и просмотра web-страниц используются специальные программы— браузеры. Всемирная паутина вызвала настоящую революцию в информационных технологиях и бум в развитии Интернета. Часто, говоря об Интернете, имеют в виду именно Всемирную паутину, однако важно понимать, что это не одно и то же. Для обозначения Всемирной паутины также используют слово веб (англ.web) и «WWW».

Документы Интернета, предназначенные для отображения в электронной форме, можно просмотреть с помощью Web-браузера, установленного на компьютере пользователя. Браузер (browser) — программа для отображения и работы с гипертекстовыми документами.

В настоящее время существует достаточное количество Web-браузеров. Наиболее известными являются Internet Explorer, Netscape Navigator, Opera, NoTrax, Google, Safari, Mozilla Firefox и др.,

Открытие и просмотр Web-страниц

Открыть Web-страницу можно:

  •  введя URL-адpecWeb-страницы в поле панели Адрес, и щелкнув на кнопке Переход.
  •  выбрав URL-адpecWeb-страницы в раскрывающемся списке панели Адрес, и щелкнув на кнопке Переход.

ОткрытаяWeb-страница отображается в рабочей области окна обозревателя. По умолчанию воспроизводится все ее содержимое, включая графические иллюстрации и встроенные мультимедийные объекты.

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

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

Адрес URL, на который указывает ссылка, отображается в строке состояния. При щелчке на гиперссылке соответствующаяWeb-страница загружается вместо текущей. Если гиперссылка указывает на произвольный файл, его загрузка происходит по протоколу FTP.

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

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

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

  •  сохранить как файл (Сохранить рисунок как);
  •  использовать как фоновый рисунок (Сделать рисунком рабочего стола) или как активный элемент (Сохранить как элемент рабочего стола).

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

Приемы управления InternetExplorer

Кнопки панели инструментов:

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

Команды меню:

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

Запись информации с Web-страниц на диск

Запись содержания всей страницы:

1) Выполнить команду Файл Сохранитькак;

2) В поле Имя файла задать имя;

3) В поле Тип файла выбрать:

  •  Веб-страница, полность – сохраняет страницу целиком (автоматически создается одноименная папка с файлом, в которую помещаются графические объекты страницы);
  •  Веб-страница, только HTML – сохраняет текст и форматирование страницы, для рисунков и других объектов указывается только местоположение;
  •  Текстовый файл – сохраняет только неформатированный текст;

4) Выбрать вид кодировки;

5) Нажать кнопкуСохранить.

Запись фрагмента страницы:

1) Выделить фрагмент;

2) Скопировать его в буфер обмена;

3) Запустить текстовый редактор (процессор);

4) Вставить фрагмент;

5) Сохранить обычным образом.

Запись графической картинки или анимации:

1) Вызвать контекстное меню объекта;

2) Выбрать командуСохранить рисунок как;

3) Выбрать диск, папку, задать имя, выбрать тип файла;

4) Нажать кнопкуСохранить.

Задание

Открыть браузер, открыть с помощью адресной строки поисковую систему www.yandex.ru, открыть каталог«картинки», в окне поиска ввести слово «Природа», выбрать и загрузить понравившееся изображение. В окне поиска ввести название сайта в соответствие с вашим вариантом, выбрать нужный сайт среди результатов поиска и перейти на него. Найти нужный для вашего варианта файл на сайте и скачать этот файл.Добавить данный сайт в избранное, выбрать сделанную закладку и перейти на неё. Просмотреть скаченные файлы, составить краткую аннотацию о проделанной работе и включить её в отчёт.

  1.  Файл Grapher Demo, сайт www.exponenta.ru
  2.  Информация о гербе России, сайт nauka.relis.ru
  3.  Информация о Ниагарском водопаде, сайт www.ru.wikipedia.org
  4.  Файл таблица интегралов от рациональных функций, сайт www.webmath.ru
  5.  Файл таблица производных, сайт www.webmath.ru
  6.  Файлкалькулятор комплексных чисел, сайт www.exponenta.ru
  7.  Статья Зелёная миля, сайт nauka.relis.ru
  8.  Информация о Москве, сайт www.ru.wikipedia.org
  9.  Файл таблица Менделеева, сайт www.webmath.ru
  10.   Файл таблица умножения, сайт www.webmath.ru
  11.   Файл сочинение «Сказка о мёртвой царевне и семи богатырях» А.С. Пушкина, сайт www.litra.ru
  12.  Файл сочинение Выразительные средства поэмы Н.А. Некрасова «Мороз, Красный нос», сайт www.litra.ru
  13.   Файл Демонстрационный вариант ЕГЭ по математике 2010, сайт www.litra.ru
  14.   Файл Демонстрационный вариант ЕГЭ по математике 2009, сайт www.litra.ru
  15.   Файл Демонстрационный вариант ЕГЭ по русскому языку 2010, сайт www.litra.ru
  16.   Файл Демонстрационный вариант ЕГЭ по русскому языку 2009, сайт www.litra.ru
  17.   Файл Демонстрационный вариант ЕГЭ по Информатике и ИКТ 2010, сайт www.litra.ru
  18.   Файл Демонстрационный вариант ЕГЭ по Информатике и ИКТ 2009, сайт www.litra.ru
  19.   Файл Демонстрационный вариант ЕГЭ по Физике 2010, сайт www.litra.ru
  20.  Файл Демонстрационный вариант ЕГЭ по Физике 2009, сайт www.litra.ru

Порядок выполнения работы (на примере)

ЕГЭ по физике 2008, www.litra.ru

1. На панели Адрес программы InternetExplorer введите адрес поисковой системы: http://www.yandex.ru/

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

3. Найдите каталог «Картинки», откройте его, введите в окне поиска слово «Природа» и загрузите на компьютер любое изображение.

4. Перейдите на главную страницу, в окне поиска введите www.litra.ru, перейдите на этот сайт.

5. Найдите нужный файл на сайте и загрузите его.

6. Добавьте сайт в папку избранное и перейдите на сайт.

7. Убедитесь, что вы скачали нужные файлы.

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Краткое содержание проделанной работы со скриншотами.
  3.  Ответы на контрольные вопросы
  4.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что такое Интернет?
  2.  Что такое WWW?
  3.  Что такое web-страница?
  4.  Что такое web-сайт?
  5.  Что такое браузер?
  6.  Какие стандарты поддерживает браузер в настоящее время?
  7.  Приведите пример HTML-5?

Лабораторная работа 13

Электронная почты

Цель

Получить навыки настройки учетной записи электронной почты.

Задание для самостоятельной подготовки

  1.  Изучить работу с программой OutlookExpress. [1], стр. 243-247.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

Электронная почта - обмен почтовыми сообщениями с любым абонентом сети Internet.

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

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

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

Задание к работе

  1.  Рассмотреть основные возможности почтовых клиентов OutlookExpress.
  2.  Создать новую учетную запись электронной почты.
  3.  Сделать выводы о преимуществах(недостатках) рассматриваемых почтовых клиентов.
  4.  Назовите основные режимы работы с веб-страницей
  5.  Назовите основные разделы главного меню
  6.  Порядок создания почтового ящика в среде Интернет.
  7.  Дайте характеристику режима написания сообщения и просмотра электронной корреспонденции.
  8.  Дайте характеристику режимов создания сообщения с вложенными файлами.
  9.  Дайте характеристику электронной почтовой системы mail.ru.
  10.  Дайте характеристику электронной почтовой системы yandex.ru.
  11.  Дайте характеристику электронной почтовой системы rambler.ru.
  12.  Каковы преимущества электронной почты?
  13.  Что такое электронная почта? Назовите ее основные преимущества и области применения.
  14.  Понятие электронного адреса, его структура. Правила выбора имени и пароля пользователя.
  15.  Режимы работы с e-mail? Основные протоколы e-mail.
  16.  Реализация технологии клиент/сервер. Примеры почтовых программ, их назначение, функции, критерии выбора.
  17.  Структура, содержание и размер почтового сообщения. Передача вложенных файлов.
  18.  Правила оформления электронных писем, использование аббревиатур и смайликов (примеры).
  19.  Порядок регистрации и использования бесплатного почтового ящика. Примеры бесплатных почтовых серверов, их возможности.
  20.  Что такое списки рассылки? Приведите пример.

Порядок выполнения работы

  1.  Изучите настоящие указания, уточните непонятные моменты.
  2.  Запустите программу OutlookExpress (InternetMail) при помощи ярлыка на рабочем столе либо Главного меню Пуск -> Программы->OutlookExpress (InternetMail).
  3.  Создание новой учетной записи электронной почты
  4.  Выберите в меню Сервис пункт Учетные записи: (Выберите в меню Вид пункт Параметры:)
  5.  В появившемся окне нажать кнопкуДобавить -> Почта: (Перейдите на вкладку Сервер)
  6.  Введите имя: Лабораторная работа 11. Нажмите кнопкуДалее > (Введите имя: Лабораторная работа 11.)
  7.  Адрес электронной почты: [любое_имя]@mail.gasu.ruНажмите кнопку Далее > (Адрес электронной почты: [любое_имя]@gasu.gorny.ru)
  8.  Сервер входящих сообщений:POP3Сервер входящих сообщений (POP3, IMAP или HTTP):mail.gasu.ruСервер исходящих сообщений (SMTP):mail.gasu.ru Нажмите кнопку Далее > (Сервер входящих сообщений:mail.gasu.ruСервер исходящих сообщений:mail.gasu.ru)
  9.  Имя для входа: Имя, указанное в п.п. 10 Пароль: 123 Нажмите кнопку Далее >
  10.  Нажмите кнопку Готово
  11.  Настройка учетной записи электронной почты
  12.  В окне Учетные записи в Интернете выберите вкладку Почта.
  13.  Выберите учетную запись mail.gasu.ru, нажмите кнопку Свойства
  14.  В открывшемся окне:
  •  На вкладке Общие отметьте заполняемые поля, уточните их назначение при помощи кнопки?(правый верхний угол окна). Законспектируйте.
  •  На вкладке Серверы отметьте заполненные поля, уточните их назначение при помощи кнопки?(правый верхний угол окна). Законспектируйте.
  •  На вкладках Подключение и Безопасность отметьте заполняемые поля, уточните их назначение при помощи кнопки?(правый верхний угол окна). Законспектируйте.
  •  На вкладке Дополнительно отметьте заполненные поля, уточните их назначение при помощи кнопки?(правый верхний угол окна). Установите флажокОставлять копии сообщений на сервере.(Нажмите кнопку Дополнительно. В окне Дополнительно отметьте заполненные поля, уточните их назначение при помощи кнопки ?. Установите флажокОставлять копии сообщений на сервере.)
  •  Нажмите кнопку OK
    1.  По результатам исследование заполните таблицу:

Поле

Значение

Название учетной записи

Имя пользователя

Адрес электронной почты

Тип сервера входящей почты

Сервер входящей почты

Номер порта сервера для входящей почты

Тип сервера исходящей почты

Сервер исходящей почты

Номер порта сервера для исходящей почты

Учетная запись на сервере

  1.  Выберите в меню Сервис пункт Учетные записи: Перейдите на вкладку Почта
  2.  Выберите учетную запись mail.gasu.ru, нажмите кнопку Удалить
  3.  Нажмите кнопку OK
  4.  Закройте окно программы кнопкой Х.

Отчет о работе

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание и данные варианта работы.
  3.  Краткое содержание проделанной работы со скриншотами и заполненной таблицей.
  4.  Ответы на контрольные вопросы.
  5.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Порядок настройки учетной записи электронной почты;
  2.  Что такое: учетная запись, POP3, SMTP, сервер входящей (исходящей) почты, порт;
  3.  Принцип передачи сообщений в электронной почте;
  4.  Формат почтового сообщения;
  5.  Что необходимо для использования электронной почты.
  6.  Какие возможности предоставляет почта?

Лабораторная работа № 14.

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

Цель работы

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

Задания для самостоятельной подготовки

1.Изучить основными понятиями, связанные с алгоритмами[1], стр. 188-191.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Термин алгоритмпроисходит от имени средневекового узбекского математика Аль-Хорезми, который еще в IX в. (825) дал правила выполнения четырех арифметических действий в десятичной системе счисления. Процесс выполнения арифметических действий был назван алгоризмом.

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

К 1950 г. алгорисмусстал алгорифмом.Смысл алгорифма чаще всего связывался с алгорифмами Евклида — процессами нахождения наибольшего общего делителя двух натуральных чисел, наибольшей общей меры двух отрезков и т.п.[1]

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

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

Уточним понятие словесного представления алгоритма на примере нахождения произведения n натуральных чисел — факториал числа п

(с = л!), т.е. вычисления по формуле с = 1∙2∙3∙4∙...∙n.

Этот процесс может быть записан в виде следующей системы последовательных указаний (пунктов):

  1.  Полагаем сравным единице и переходим к следующему пункту.
  2.  Полагаем i равным единице и переходим к следующему пункту.
  3.  Полагаем с = i • с и переходим к следующему пункту.
  4.  Проверяем, равно ли i числу п. Если i = п, то вычисления прекращаем. Если i<п, то увеличиваем i на единицу и  переходим к пункту 3.

Рассмотрим еще один пример алгоритма — нахождение наименьшего числа М в последовательности из пчисел a12, ..., аn (п≠ 0). Прежде чем записать словесный алгоритм данного примера, детально рассмотрим сам процесс поиска наименьшего числа. Будем считать, что процесс поиска осуществляется следующим образом. Первоначально в качестве числа M принимается a1 т. е. полагаем М = а1, после чего М сравниваем с последующими числами последовательности, начиная с а2. Если М< а2, то М сравнивается с a3, если М< а3, то М сравнивается с a4, и так до тех пор, пока найдется число аi< М. Тогда полагаем М = ai и продолжаем сравнение с М последующих чисел из последовательности, начиная с ai+1, и так до тех пор, пока не будут просмотрены все пчисел. В результате просмотра всех чисел М будет иметь значение, равное наименьшему числу из последовательности (I— текущий номер числа). Этот процесс может быть записан в виде следующей системы последовательных указаний:

  1.  Полагаем i = 1 и переходим к следующему пункту.
  2.  Полагаем М = aiи переходим к следующему пункту.
  3.  Сравниваем i с п; если i<п, переходим к 4 пункту, если i = п, процесс поиска останавливаем.
  4.  Увеличиваем i на 1 и переходим к следующему пункту.
  5.  Сравниваем aiс М. Если М< аi, то переходим к пункту 3, иначе (M>аi) переходим к пункту 2.

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

Алгоритмы, в соответствии с которыми решение поставленных задач сводится к арифметическим действиям, называются численными алгоритмами.

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

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

Решение задач является скорее искусством, чем наукой. Доказательством этого может служить тот факт, что представленные ниже, весьма расплывчато определенные фазы решения задач, предложенные математиком Дж. Полиа (G.Polya) в 1945 году, остаются теми основными принципами, на которых и  сегодня базируется обучение навыкам решения задач.

Фаза 1. Понять существо задачи.

Фаза 2. Разработать план решения задачи.

Фаза  3. Выполнить план.

Фаза  4. Оценить точность решения, а также его потенциал в качестве  средства для решения других задач.

Применительно к процессу разработки программ эти фазы выглядят  следующим образом:

Фаза 1. Понять существо задачи.

Фаза2. Предложить идею, какая алгоритмическая процедура позволила бы решить задачу.

Фаза 3. Сформулировать алгоритм и представить его в виде программы.

Фаза 4. Оценить точность программы и ее потенциал в качестве средства для решения других задач.

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

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

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

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

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

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

Это очень важная особенность алгоритмов. Наличие алгоритма формализовало процесс, исключило рассуждения. Если обратиться к другим примерам алгоритмов, то можно увидеть, что и они позволяют исполнителю действовать формально. Таким образом, создание алгоритма дает возможность решать задачу формально, механически исполняя команды алгоритма в указанной последовательности.

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

Базовые структуры алгоритмов— это определенный набор блоков и стандартных способов их соединения для выполнения типичных последовательностей действий. К основным структурам относятся следующие: линейные (рис. 1,а), разветвляющиеся (рис. 1, б), циклические (рис. 1, в, г).

Рисунок 1 — Базовые структуры алгоритмов и программ

Линейныминазываются алгоритмы, в которых действия осуществляются последовательно друг за другом. Стандартная блок-схема линейного алгоритма приводится на рис. 2, а (вычисление произведения двух чисел — А и В).

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

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

Примером может являться разветвляющийся алгоритм, изображенный на рис. 2, б. Аргументами этого алгоритма являются числаА и В, а результатом — число X. Если условиеА>= Вистинно, то выполняется операция умножения чисел (X = А * В), в противном случае выполняется операция сложения (X= А + В).В результате печатается то значение X, которое получается в результате выполнения одного из действий.

Циклическимназывается алгоритм, в котором некоторая часть операций (тело цикла — последовательность команд) выполняется многократно. Однако слово «многократно» не значит «до бесконечности». Организация циклов, никогда не приводящая к остановке в выполнении алгоритма, является нарушением требования его результативности — получения результата за конечное число шагов.

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

Возможен другой случай, когда тело цикла выполняется по крайней мере один раз и будет повторяться до тех пор, пока не станет истинным условие. Такая организация цикла, когда его тело расположено перед проверкой условия, носит название цикла с постусловием, или цикла типа до(рис. 2, г). Истинность условия в этом случае — условие окончания цикла. Отметим, что возможна ситуация с постусловием и при организации цикла-пока. Итак, цикл-до завершается, когда условие становится истинным, а цикл-пока— когда условие становится ложным.

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

Рассмотрим циклический алгоритм типа пока(рис. 2, в) на примере алгоритма вычисления факториала. N— число, факториал которого вычисляется. Начальное значение N! принимается равным 1. K будет меняться от 1 до Nи вначале также равно 1. Цикл будет выполняться, пока справедливо условие N< К. Тело цикла состоит из двух операций N!=N!*КиК = К + 1(рис. 1.3, в).

Циклические алгоритмы, в которых тело цикла выполняется заданное число раз, реализуются с помощью цикла со счетчиком. Цикл со счетчиком реализуется с помощью рекурсивного увеличения значения счетчика в теле цикла (К = К + 1 в алгоритме вычисления факториала).

Рисунок 2 — Примеры структур алгоритмов:

а— линейный алгоритм;  б—  алгоритм с ветвлением; в — алгоритм с циклом;

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

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

Задание

Разработать алгоритм решения следующей задачи:

  1.  Крестьянину нужно перевезти через реку волка, козу и капусту. Лодка небольшая: в ней может поместиться крестьянин, а с ним или только коза, или только волк, или только капуста. Но если оставить волка с козой, то волк сьест козу, а если оставить козу с капустой, то коза сьест капусту. Как перевез свой груз крестьянин?
  2.  Имеется две кучки спичек. В первой 7 спичек, во второй - 5. За один ход разрешается взять любое количество спичек, но из одной кучки. Проигрывает тот, кому нечего брать. Кто выигрывает при правильной игре - начинающий или его партнер? И как для этого ему надо играть? 
  3.  На сковороде могут одновременно жариться две котлеты. Каждую котлету нужно обжаривать с двух сторон, при этом на обжаривание ее с одной стороны требуется 2 мин. Голодный студент мечтает побыстрее поджарить три котлеты. Какое наименьшее время ему потребуется? 
  4.  Четыре стакана поставлены кверху дном в четырех углах вращающегося квадpатного стола. Вы хотите пеpевеpнуть их в одну стоpону: или все ввеpх или все вниз. Вы можете взять любые два стакана, и должны пеpевеpнуть один или два из них. Есть два условия: у вас завязаны глаза, и стол повоpачивается на произвольное число оборотов каждый pаз, когда вы дотpагиваетесь до стаканов. Так что вы будете делать? 
  5.  Семья (папа, мама, сын и бабушка) ночью подошла к мосту, способному выдержать только двух человек одновременно. По мосту можно двигаться только с фонариком. Известно, что папа может перейти мост в одну сторону за минуту, мама - за две, сын - за пять и бабушка - за десять минут. Фонарик у них один. Светить издали нельзя. Носить друг друга на руках тоже. Если по мосту идут двое, время перехода определяется наиболее медлительным членом семьи. Как семье переправиться за 17 минут?
  6.  Два игрока кладут по очереди пятаки на круглый стол так, чтобы пятаки не накладывались друг на друга. Проигрывает тот, кто не сможет положить пятака. Кто выигрывает при правильной игре и как он должен для этого играть?
  7.  Три актера готовятся к спектаклю. С ними работают два опытных гримера. Каждый актер должен быть накрашен и причесан. Макияж у каждого актера продолжается полчаса, а причесывание только 10 минут.Как быстро три актера смогут подготовиться к выходу на сцену?
  8.  Нужно положить восемь монет на стол в один ряд, вот так:За один ход ты берешь одну монету, переносишь ее через две соседние монеты (монеты, а не стопки!) и кладешь на третью. За четыре хода должны получиться четыре стопки по две монеты в каждой.

  1.  Трое учеников пошли на рыбалку, взяв с собой лодку, выдерживающую нагрузку до 100 кг. Как перебраться ученикам с берега реки на остров, если их массы равны 40 кг, 50 кг, 70 кг? 
  2.  На столе лежат 37 спичек. Каждому из двух игроков разрешается по очереди брать не более 5 спичек. Выигрывает тот, кто возьмет последнюю. Кто выигрывает при правильной стратегии - начинающий игру или второй игрок? Какова выигрышная стратегия?
  3.  Командиру взвода нужно переправить через реку 10 солдат. На реке нет мостов, и ни один солдат не пожелал переплывать реку вплавь. Тут командир увидел лодку, в которой сидели два мальчика. Лодка могла удержать либо двоих мальчиков, либо одного солдата.Как командир переправил солдат на другой берег, используя лодку? 
  4.  Три миссионера и три каннибала должны пересечь реку в лодке, в которой могут поместиться только двое. Миссионеры должны соблюдать осторожность, чтобы каннибалы не получили на каком-либо берегу численное преимущество. Как переплыть реку? 
  5.  Вам нужно переправить через реку с помощью одного плота семью (мать, отца, 2-х дочерей и 2-х сыновей) и полицейского с заключенным.
    Правила:

1. На плоту могут одновременно перемещаться максимум 2 человека.

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

3. Маме не разрешается находиться с сыновьями без присутствия отца.

4. Заключённого нельзя оставлять без полицейского ни с одним из членов семьи.

5. Управлять плотом могут только полицейский и родители. 

  1.  Трём хирургам необходимо последовательно прооперировать в полевых условиях больного, страдающего заразным заболеванием. Сами хирурги тоже больны, причём все - разными болезнями. В распоряжении хирургов есть лишь две пары стерильных перчаток. Подскажите план операции, после которой ни хирурги, ни больной не заразятся друг от друга. (Помогать друг другу во время операций хирурги не должны.Оперировать одной рукой нельзя.) 
  2.  Верблюд выращивает бананы. В этом году он собрал богатый урожай - 3000 бананов. Но вот незадача - ближайшее место, где их можно продать, находится за 1000 км. За один раз верблюд может унести не более 1000 бананов, при этом за каждый километр пути он съедает 1 банан.
    Какое максимальное количество бананов может продать верблюд?
  3.  Четыре шахтера, которые имеют один фонарь, должны пройти через шахту. Одновременно по шахте могут двигаться не больше двух человек, и каждый шахтер, двигаясь в шахте, должен иметь фонарь. Шахтеры, имена которых Эндрю, Блэйк, Джонсон и Келли, могут пройти шахту за одну, две, три и четыре минуты соответственно. Когда два шахтера идут вместе, они движутся со скоростью более медленного из них. Каким образом шахтеры могут пройти через шахту за 15 минут? После того как вы решите задачу, объясните, с чего вы начали решение.
  4.  Король, его сын принц и дочь принцесса находились в темнице высокой башни. Они весили 195, 105 и 90 фунтов соответственно. Еду им поднимали в двух корзинах, прикрепленных к концам длинного каната. Канат был перекинут через балку, вбитую под самой крышей. Получалось так, что, когда одна корзина находилась на земле, вторая находилась на уровне оконца в камере пленников. Эти корзины оставались единственной надеждой на спасение. Естественно, как только одна корзина становилась тяжелее другой она опускалась. Однако если разница в весе превышает 15 фунтов, корзина стремительно неслась вниз. Единственное что помогло бы пленникам бежать из плена, было находившееся в камере пушечное ядро весом 75 фунтов - его можно было попытаться использовать как противовес. Как пленникам удалось бежать? 
  5.  Три второклассника делят 24 яблока. Пока у них есть три кучки: 11, 7 и 6 яблок соответственно, но они хотят поделить их поровну. Один из этих второклассников, хитрый математик, предложил двум другим такое пари:- Вы должны будете уравнять количество яблок в кучках, но строго по моей системе: из одной кучки берёте столько яблок, сколько их в той кучке, куда вы добавлять собираетесь. Но сделать это вы должны строго за 3 перекладывания. Сможете - все яблоки ваши, нет - они мои.- Давай! - согласились двое. Подумали с минутку и сумели так сделать. И вот они, довольно хрумкая яблоками, утопали от вредного математика. А вы бы смогли так сделать?
  6.  Допустим, у нас есть большой и маленький стаканчики для вина. Сначала наполним вином маленький стаканчик и перельем его в большой стакан. Затем наполним водой маленький стакан, перельем некоторое количество воды в большой стакан и смешаем его с вином. Теперь будем переливать смесь обратно в маленький стакан, пока он не наполнится. Чего теперь больше в маленьком стакане — воды в вине или вина в воде?
  7.  Две пчелы, Ромео и Джульетта, живут в разных ульях, но они встретились и полюбили друг друга. Однажды безветренным весенним утром они одновременно вылетели из своих ульев, чтобы слетать друг к другу в гости. В 50-ти метрах от ближайшего улья они встретились, но не заметили друг друга и полетели дальше. Прибыв к месту своего назначения, они потратили одинаковое время, чтобы выяснить, что того, к кому они прилетели, нет дома, и повернуть назад. На обратном пути они встретились в точке, находящейся на расстоянии 20 метров от ближайшего улья. На этот раз они увидели друг друга и устроили пикник, прежде чем возвратиться домой. На каком расстоянии друг от друга расположены их улья?

Примеры выполнения работы

Пример №1.

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

Решение.Обозначим пары через Аа, Бб, Вв (маленькими буквами обозначим женщин). Вот схема перевозок, реализующая нужную переправу за 11 рейсов: (стрелки указывают направление движения лодки).

Рейс

Левый берег

В лодке

Правый берег

 1

 БбВв

 Аа=>

 Аа

 2

 А БбВв

 <=А

 а

 3

 А Б В

 б в=>

 а б в

 4

 Аа Б В

 <=а

 б в

 5

 Аа

 Б В=>

 БбВв

 6

 АаБб

 <=Бб

 Вв

 7

 а б

 А Б=>

 А Б Вв

 8

 а б в

 <=в

 А Б В

 9

 а

 б в=>

 А БбВв

 10

 а б

 <=б

 А Б Вв

 11

 

 а б=>

 АаБбВв

Пример №2.

Задача. Имеются два кувшина емкостью 3 и 8 л. Необходимо составить алгоритм, с помощью которого, пользуясь только этими двумя кувшинами, можно набрать 7 л воды.

Можно предположить, что кувшин емкостью 3 л необходимо использовать для того, чтобы отлить в него 1 л из полного кувшина емкостью 8 л. Таким образом, решение задачи сводится к поиску возможности поместить, например, 2 л воды в трехлитровый кувшин, затем наполнить восьмилитровый и перелить из него воду в трехлитровый кувшин, в котором до полного заполнения не хватает ровно I л. Задача реализуется следующим линейным алгоритмом (А — количество воды в трехлитровом кувшине, В — количество воды в восьмилитровом кувшине):

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные по заданному варианту лабораторной работы.
  3.  Описание хода выполнения работы.
  4.  Результат выполнения работы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Назовите основные фазы, которые должны быть выполнены в процессе решения задачи.
  2.  Являются ли эти фазы этапами, которым нужно непременно следовать при решении задачи?
  3.  Что понимали под понятием алгоритм?
  4.  В чем состоит различие между численными алгоритмами и логическими алгоритмами?
  5.  Перечислите свойства алгоритмов.
  6.  Какова важная особенность алгоритмов?
  7.  С помощью чего реализуется цикл со счетчиком?
  8.  На какие этапы может разбиваться процесс разработки сложного алгоритма и как они называются?

Лабораторная работа № 15

Создание алгоритма

Цель работы

Изучить последовательность и содержание этапов создания алгоритмов.

Задания для самостоятельной подготовки

1.Изучить различные подходы к решению алгоритмических задач[1], стр. 198-204.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Решение алгоритмических задач является скорее искусством, чем наукой. Доказательством этого может служить тот факт, что представленные ниже, весьма расплывчато определенные фазы решения задач, предложенные математиком Дж. Полиа (G.Polya) в 1945 году, остаются теми основными принципами, на которых и  сегодня базируется обучение навыкам решения задач.

Фаза 1. Понять существо задачи.

Фаза 2. Разработать план решения задачи.

Фаза  3. Выполнить план.

Фаза  4. Оценить точность решения, а также его потенциал в качестве  средства для решения других задач.

Применительно к процессу разработки программ эти фазы выглядят  следующим образом:

Фаза 1. Понять существо задачи.

Фаза2. Предложить идею, какая алгоритмическая процедура позволила бы решить задачу.

Фаза 3. Сформулировать алгоритм и представить его в виде программы.

Фаза 4. Оценить точность программы и ее потенциал в качестве средства для решения других задач.

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

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

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

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

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

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

Это очень важная особенность алгоритмов. Наличие алгоритма формализовало процесс, исключило рассуждения. Если обратиться к другим примерам алгоритмов, то можно увидеть, что и они позволяют исполнителю действовать формально. Таким образом, создание алгоритма дает возможность решать задачу формально, механически исполняя команды алгоритма в указанной последовательности.

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

Базовые структуры алгоритмов— это определенный набор блоков и стандартных способов их соединения для выполнения типичных последовательностей действий. К основным структурам относятся следующие: линейные (рис. 1,а), разветвляющиеся (рис. 1, б), циклические (рис. 1, в, г).

Рисунок 1 — Базовые структуры алгоритмов и программ

Линейныминазываются алгоритмы, в которых действия осуществляются последовательно друг за другом. Стандартная блок-схема линейного алгоритма приводится на рис. 2, а (вычисление произведения двух чисел — А и В).

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

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

Примером может являться разветвляющийся алгоритм, изображенный на рис. 2, б. Аргументами этого алгоритма являются числаА и В, а результатом — число X. Если условиеА>= Вистинно, то выполняется операция умножения чисел (X = А * В), в противном случае выполняется операция сложения (X= А + В).В результате печатается то значение X, которое получается в результате выполнения одного из действий.

Циклическимназывается алгоритм, в котором некоторая часть операций (тело цикла — последовательность команд) выполняется многократно. Однако слово «многократно» не значит «до бесконечности». Организация циклов, никогда не приводящая к остановке в выполнении алгоритма, является нарушением требования его результативности — получения результата за конечное число шагов.

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

Возможен другой случай, когда тело цикла выполняется по крайней мере один раз и будет повторяться до тех пор, пока не станет истинным условие. Такая организация цикла, когда его тело расположено перед проверкой условия, носит название цикла с постусловием, или цикла типа до(рис. 2, г). Истинность условия в этом случае — условие окончания цикла. Отметим, что возможна ситуация с постусловием и при организации цикла-пока. Итак, цикл-до завершается, когда условие становится истинным, а цикл-пока— когда условие становится ложным.

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

Рассмотрим циклический алгоритм типа пока(рис. 2, в) на примере алгоритма вычисления факториала. N— число, факториал которого вычисляется. Начальное значение N! принимается равным 1. K будет меняться от 1 до Nи вначале также равно 1. Цикл будет выполняться, пока справедливо условие N< К. Тело цикла состоит из двух операций N!=N!*КиК = К + 1(рис. 1.3, в).

Циклические алгоритмы, в которых тело цикла выполняется заданное число раз, реализуются с помощью цикла со счетчиком. Цикл со счетчиком реализуется с помощью рекурсивного увеличения значения счетчика в теле цикла (К = К + 1 в алгоритме вычисления факториала).

Рисунок 2 — Примеры структур алгоритмов:

а— линейный алгоритм;  б—  алгоритм с ветвлением; в — алгоритм с циклом;

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

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

Задание

Разработать алгоритм решения следующей задачи:

  1.  Крестьянину нужно перевезти через реку волка, козу и капусту. Лодка небольшая: в ней может поместиться крестьянин, а с ним или только коза, или только волк, или только капуста. Но если оставить волка с козой, то волк сьест козу, а если оставить козу с капустой, то коза сьест капусту. Как перевез свой груз крестьянин?
  2.  Имеется две кучки спичек. В первой 7 спичек, во второй - 5. За один ход разрешается взять любое количество спичек, но из одной кучки. Проигрывает тот, кому нечего брать. Кто выигрывает при правильной игре - начинающий или его партнер? И как для этого ему надо играть? 
  3.  На сковороде могут одновременно жариться две котлеты. Каждую котлету нужно обжаривать с двух сторон, при этом на обжаривание ее с одной стороны требуется 2 мин. Голодный студент мечтает побыстрее поджарить три котлеты. Какое наименьшее время ему потребуется? 
  4.  Четыре стакана поставлены кверху дном в четырех углах вращающегося квадpатного стола. Вы хотите пеpевеpнуть их в одну стоpону: или все ввеpх или все вниз. Вы можете взять любые два стакана, и должны пеpевеpнуть один или два из них. Есть два условия: у вас завязаны глаза, и стол повоpачивается на произвольное число оборотов каждый pаз, когда вы дотpагиваетесь до стаканов. Так что вы будете делать? 
  5.  Семья (папа, мама, сын и бабушка) ночью подошла к мосту, способному выдержать только двух человек одновременно. По мосту можно двигаться только с фонариком. Известно, что папа может перейти мост в одну сторону за минуту, мама - за две, сын - за пять и бабушка - за десять минут. Фонарик у них один. Светить издали нельзя. Носить друг друга на руках тоже. Если по мосту идут двое, время перехода определяется наиболее медлительным членом семьи. Как семье переправиться за 17 минут?
  6.  Два игрока кладут по очереди пятаки на круглый стол так, чтобы пятаки не накладывались друг на друга. Проигрывает тот, кто не сможет положить пятака. Кто выигрывает при правильной игре и как он должен для этого играть?
  7.  Три актера готовятся к спектаклю. С ними работают два опытных гримера. Каждый актер должен быть накрашен и причесан. Макияж у каждого актера продолжается полчаса, а причесывание только 10 минут.Как быстро три актера смогут подготовиться к выходу на сцену?
  8.  Нужно положить восемь монет на стол в один ряд, вот так:За один ход ты берешь одну монету, переносишь ее через две соседние монеты (монеты, а не стопки!) и кладешь на третью. За четыре хода должны получиться четыре стопки по две монеты в каждой.
  9.  
  10.  Трое учеников пошли на рыбалку, взяв с собой лодку, выдерживающую нагрузку до 100 кг. Как перебраться ученикам с берега реки на остров, если их массы равны 40 кг, 50 кг, 70 кг? 
  11.  На столе лежат 37 спичек. Каждому из двух игроков разрешается по очереди брать не более 5 спичек. Выигрывает тот, кто возьмет последнюю. Кто выигрывает при правильной стратегии - начинающий игру или второй игрок? Какова выигрышная стратегия?
  12.  Командиру взвода нужно переправить через реку 10 солдат. На реке нет мостов, и ни один солдат не пожелал переплывать реку вплавь. Тут командир увидел лодку, в которой сидели два мальчика. Лодка могла удержать либо двоих мальчиков, либо одного солдата.Как командир переправил солдат на другой берег, используя лодку? 
  13.  Три миссионера и три каннибала должны пересечь реку в лодке, в которой могут поместиться только двое. Миссионеры должны соблюдать осторожность, чтобы каннибалы не получили на каком-либо берегу численное преимущество. Как переплыть реку? 
  14.  Вам нужно переправить через реку с помощью одного плота семью (мать, отца, 2-х дочерей и 2-х сыновей) и полицейского с заключенным.

Правила:

1. На плоту могут одновременно перемещаться максимум 2 человека.

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

3. Маме не разрешается находиться с сыновьями без присутствия отца.

4. Заключённого нельзя оставлять без полицейского ни с одним из членов семьи.

5. Управлять плотом могут только полицейский и родители. 

  1.  Трём хирургам необходимо последовательно прооперировать в полевых условиях больного, страдающего заразным заболеванием. Сами хирурги тоже больны, причём все - разными болезнями. В распоряжении хирургов есть лишь две пары стерильных перчаток. Подскажите план операции, после которой ни хирурги, ни больной не заразятся друг от друга. (Помогать друг другу во время операций хирурги не должны.Оперировать одной рукой нельзя.) 
  2.  Верблюд выращивает бананы. В этом году он собрал богатый урожай - 3000 бананов. Но вот незадача - ближайшее место, где их можно продать, находится за 1000 км. За один раз верблюд может унести не более 1000 бананов, при этом за каждый километр пути он съедает 1 банан.
    Какое максимальное количество бананов может продать верблюд?
  3.  Четыре шахтера, которые имеют один фонарь, должны пройти через шахту. Одновременно по шахте могут двигаться не больше двух человек, и каждый шахтер, двигаясь в шахте, должен иметь фонарь. Шахтеры, имена которых Эндрю, Блэйк, Джонсон и Келли, могут пройти шахту за одну, две, три и четыре минуты соответственно. Когда два шахтера идут вместе, они движутся со скоростью более медленного из них. Каким образом шахтеры могут пройти через шахту за 15 минут? После того как вы решите задачу, объясните, с чего вы начали решение.
  4.  Король, его сын принц и дочь принцесса находились в темнице высокой башни. Они весили 195, 105 и 90 фунтов соответственно. Еду им поднимали в двух корзинах, прикрепленных к концам длинного каната. Канат был перекинут через балку, вбитую под самой крышей. Получалось так, что, когда одна корзина находилась на земле, вторая находилась на уровне оконца в камере пленников. Эти корзины оставались единственной надеждой на спасение. Естественно, как только одна корзина становилась тяжелее другой она опускалась. Однако если разница в весе превышает 15 фунтов, корзина стремительно неслась вниз. Единственное что помогло бы пленникам бежать из плена, было находившееся в камере пушечное ядро весом 75 фунтов - его можно было попытаться использовать как противовес. Как пленникам удалось бежать? 
  5.  Три второклассника делят 24 яблока. Пока у них есть три кучки: 11, 7 и 6 яблок соответственно, но они хотят поделить их поровну. Один из этих второклассников, хитрый математик, предложил двум другим такое пари:- Вы должны будете уравнять количество яблок в кучках, но строго по моей системе: из одной кучки берёте столько яблок, сколько их в той кучке, куда вы добавлять собираетесь. Но сделать это вы должны строго за 3 перекладывания. Сможете - все яблоки ваши, нет - они мои.- Давай! - согласились двое. Подумали с минутку и сумели так сделать. И вот они, довольно хрумкая яблоками, утопали от вредного математика. А вы бы смогли так сделать?
  6.  Допустим, у нас есть большой и маленький стаканчики для вина. Сначала наполним вином маленький стаканчик и перельем его в большой стакан. Затем наполним водой маленький стакан, перельем некоторое количество воды в большой стакан и смешаем его с вином. Теперь будем переливать смесь обратно в маленький стакан, пока он не наполнится. Чего теперь больше в маленьком стакане — воды в вине или вина в воде?
  7.  Две пчелы, Ромео и Джульетта, живут в разных ульях, но они встретились и полюбили друг друга. Однажды безветренным весенним утром они одновременно вылетели из своих ульев, чтобы слетать друг к другу в гости. В 50-ти метрах от ближайшего улья они встретились, но не заметили друг друга и полетели дальше. Прибыв к месту своего назначения, они потратили одинаковое время, чтобы выяснить, что того, к кому они прилетели, нет дома, и повернуть назад. На обратном пути они встретились в точке, находящейся на расстоянии 20 метров от ближайшего улья. На этот раз они увидели друг друга и устроили пикник, прежде чем возвратиться домой. На каком расстоянии друг от друга расположены их улья?

Порядок выполнения работы

Пример №1.

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

Решение.Обозначим пары через Аа, Бб, Вв (маленькими буквами обозначим женщин). Вот схема перевозок, реализующая нужную переправу за 11 рейсов: (стрелки указывают направление движения лодки).

Рейс

Левый берег

В лодке

Правый берег

 1

 БбВв

 Аа=>

 Аа

 2

 А БбВв

 <=А

 а

 3

 А Б В

 б в=>

 а б в

 4

 Аа Б В

 <=а

 б в

 5

 Аа

 Б В=>

 БбВв

 6

 АаБб

 <=Бб

 Вв

 7

 а б

 А Б=>

 А Б Вв

 8

 а б в

 <=в

 А Б В

 9

 а

 б в=>

 А БбВв

 10

 а б

 <=б

 А Б Вв

 11

 

 а б=>

 АаБбВв

Пример №2.

Задача. Имеются два кувшина емкостью 3 и 8 л. Необходимо составить алгоритм, с помощью которого, пользуясь только этими двумя кувшинами, можно набрать 7 л воды.

Можно предположить, что кувшин емкостью 3 л необходимо использовать для того, чтобы отлить в него 1 л из полного кувшина емкостью 8 л. Таким образом, решение задачи сводится к поиску возможности поместить, например, 2 л воды в трехлитровый кувшин, затем наполнить восьмилитровый и перелить из него воду в трехлитровый кувшин, в котором до полного заполнения не хватает ровно I л. Задача реализуется следующим линейным алгоритмом (А — количество воды в трехлитровом кувшине, В — количество воды в восьмилитровом кувшине):

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные по заданному варианту лабораторной работы.
  3.  Описание хода выполнения работы.
  4.  Результат выполнения работы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Назовите основные фазы, которые должны быть выполнены в процессе решения задачи.
  2.  Являются ли эти фазы этапами, которым нужно непременно следовать при решении задачи?
  3.  Что понимали под понятием алгоритм и какова важная особенность алгоритмов?
  4.  С помощью чего реализуется цикл со счетчиком?
  5.  В чем состоит различие между численными алгоритмами и логическими алгоритмами?
  6.  Перечислите свойства алгоритмов.
  7.  На какие этапы может разбиваться процесс разработки сложного алгоритма и как они называются?
  8.  Существует ли единое решение алгоритмов?

Лабораторная работа № 16

Итерационные структуры в алгоритмах

Цель работы

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

Задание для самостоятельной подготовки

1.Изучить особенности  построения итеративных структур алгоритмов [1], стр. 205-213.

2.Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Итерация — это организация обработки данных, при которой действия повторяются многократно, не приводя при этом к вызовам самих себя (не путать с рекурсией).

Когда какое-то действие необходимо повторить большое количество раз, в программировании используются циклы. Например, нужно вывести 200 раз на экран текст «Hello, World!». Вместо 200-кратного повторения одной и той же команды вывода текста часто создается цикл, который прокручивается 200 раз, и 200 раз выполняет то, что написано в теле цикла. Один шаг цикла и называется итерацией.

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

Давайте попробуем представить, как бы мы действовали при поиске определенного имени в списке гостей, содержащем около 20 фамилий. В данном случае можно было бы просмотреть весь список от начала и до конца, сравнивая каждый его элемент с искомым именем. Если требуемое имя будет найдено, поиск завершится успешно. Однако, если будет достигнут конец списка или обнаружено имя, расположенное по алфавиту после искомого, поиск завершится неудачей. (Не забывайте, что список упорядочен в алфавитном порядке, поэтому если будет найдено имя, расположенное по алфавиту после требуемого, то это означает, что нужного нам имени в списке нет.) Таким образом, наша задача — выполнять последовательный просмотр элементов списка в направлении сверху вниз до тех пор, пока не будут проверены все имена или нужное нам имя не будет найдено.

С помощью нашего псевдокода этот процесс можно представить следующим образом:

Выбрать в качестве Проверяемое Значение первый элемент Списка;

While(Искомое Значение > Проверяемое Значение и есть непроверенные элементы Списка)

do (выбрать в качестве Проверяемое Значение следующий элемент Списка)

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

if (Искомое Значение = Проверяемое Значение)

then{сообщить об успехе}

else{сообщить о неудаче}

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

if (Список пуст)

then (сообщить о неудаче)

else (...)

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

Применить процедуру Поиск к списку пассажиров, чтобы найти имя "Даррел Бейкер".

Эта инструкция позволяет установить, является ли Даррел Бейкер пассажиром некоторого рейса. Вот еще один пример:

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

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

Рисунок 1 - Алгоритм последовательного поиска, записанный с помощью псевдокода

Итак, можно сказать, что представленный на рисунке 1 алгоритм последовательно рассматривает все элементы списка. По этой причине данный алгоритм называется алгоритмом последовательного поиска (sequentialsearch). Всилу своей простоты он часто применяется ккоротким спискам либо когда это необходимо по каким-то иным соображениям. Однако в случае длинных списков этот метод оказывается менее эффективным, чем другие (в чем мы скоро убедимся).

Неоднократное использование инструкции или последовательности инструкций представляет собой важную алгоритмическую концепцию. Одним из методов организации такого повторения является итеративная структура, известная как цикл (loop); здесь последовательность инструкций, называемая телом цикла, многократно выполняется под контролем некоторого управляющего процесса. Типичный пример цикла можно найти в алгоритме последовательного поиска. Здесь инструкция whileиспользуется в целях управления повторным выполнением единственной инструкции "выбрать следующий элемент списка как Проверяемое значение". Общий синтаксис инструкции while имеет такой вид:

While (условие) do {тело цикла}.

Эта инструкция представляет собой типичный образец циклической структуры, т.е. при ее выполнении циклически совершаются следующие действия:

проверить условие

выполнить тело цикла

проверить условие

выполнить тело цикл

     .   .

проверить условие

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

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

Выполнить инструкцию "Добавить каплю серной кислоты" три раза.

Эта циклическая структура эквивалентна такой последовательности инструкций:

Добавить каплю серной кислоты.

Добавить каплю серной кислоты.

Добавить каплю серной кислоты.

Однако невозможно написать аналогичную последовательность, эквивалентную следующему циклу:

while (уровень рН больше, чем 4) do{добавить каплю серной кислоты}

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

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

Управление циклом состоит из трех операций: инициализации, проверки и модификации (рисунок 2), причем все они обязательны для успешного управления циклом. Назначение операции проверки состоит в обеспечении своевременного окончания циклического процесса за счет отслеживания возникновения условия, указывающего, что цикл пора заканчивать. Это условие называют условием завершения цикла. Именно для выполнения операции проверки некоторое условие обязательно указывается при записи каждой инструкции while нашего псевдокода. Однако условие, задаваемое в инструкции while, — это условие продолжения цикла, а условие завершения — это отрицание условия, заданного в инструкции while. Поэтому в инструкции while показанной на рисунке 2, условие завершения выглядит следующим образом:

(Искомое Значение ≤ Проверяемое Значение) или (больше нет не рассмотренных элементов)

Рисунок 2 - Операции управления циклом

Остальные две операции управления циклом гарантируют, что условие завершения обязательно возникнет. Операция инициализации устанавливает начальное состояние, а операция модификации изменяет его в направлении достижения условия завершения. Например, на рисунке 1 операция инициализации выполняется инструкцией, предшествующей инструкции while. В этой операции первый элемент списка устанавливается в качестве текущего проверяемого. Операция модификации в этом случае реализуется в теле цикла, когда интересующая нас позиция (проверяемый элемент) перемещается к концу списка. Таким образом, выполнение операции инициализации и многократное выполнение операции модификации приводят к тому, что условие завершения обязательно будет достигнуто. (Или обнаружится проверяемый элемент, больший либо равный искомому, или будет достигнут конец списка.)

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

Число 1while(Число ≠ 6) do{Число Число + 2}

В данном случае условием завершения является выражение Число ≠ 6. Однако переменная Число инициализируется значением 1, а затем увеличивается на 2 на каждом этапе модификации. Таким образом, при выполнении цикла переменной число будут присваиваться значения 1, 3, 5, 7, 9,.... и ее значение никогда не будет равно 6. В результате выполнение данного цикла никогда не закончится.

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

while (условие) do {действие}

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

Рисунок 3 - Структура цикла while-do

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

Рисунок 4 - Структура repeat-until

В нашем псевдокоде общий синтаксис цикла этого типа имеет следующий вид:

repeat {действие} until (условие)

Рассмотрим конкретный пример:

repeat {взять монету из кармана} until (в кармане нет монет)

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

while (в кармане есть монета) do{взять монету из кармана}

Придерживаясь терминологии нашего псевдокода, будем называть эти структуры оператором цикла с условием продолжения и оператором цикла с условием завершения. Иногда оператор цикла while называют априорным циклом (pretestloop), или циклом с предусловием, поскольку условие завершения проверяется до выполнения тела цикла, а оператор цикла repeat называется апостериорным циклом (posttestloop), или циклом с постусловием, поскольку условие завершения проверяется после выполнения цикла.

Цикл с параметром (for). Оператор цикла с параметром for имеет следующий формат:

for( выражение_1 ; выражение_2 ; выражение_3 ) тело

Выражение_1 обычно используется для установления начального значения переменных, управляющих циклом. Выражение_2 – это выражение, определяющее условие, при котором тело цикла будет выполняться. Выражение_3 определяет изменение переменных, управляющих циклом после каждого выполнения тела цикла.

Схема выполнения оператора for:

1. Вычисляется выражение_1.

2. Вычисляется выражение_2.

3. Если значения выражения_2 отлично от нуля (истина), выполняется тело цикла, вычисляется выражение_3 и осуществляется переход к пункту 2, если выражение_2 равно нулю (ложь), то управление передается на оператор, следующий за оператором for.

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

В этом примере вычисляются квадраты чисел от 1 до 9

for (i=1; i<10; i++) b=i*i;

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

for (;;)

{ ...

  ...  break;

  ...

}

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

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

 (1)

для заданного значения х. Вычисления будем продолжать до тех пор, пока очередной член ряда остается больше заданной точности. Обозначим точность через eps, результат - b, очередной член ряда - r, номер члена ряда - i. Для получения i-ro члена ряда нужно (i-l)-й член умножить на х и разделить на i, что позволяет исключить операцию возведения в степень и явное вычисление факториала. Опустив определения переменных, операторы ввода и проверки исходных данных, а также вывода результатов, запишем три фрагмента программ.

/*  Цикл  а предусловием  */

i = 2;

b = 1.0;

r = х;

while(r >eps || r <  -eps)

{

b=b+r;

r=r*x/i;

i++ ;

}

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

/*  Цикл  с постусловием  */

i=l ;

b=0.0;

r=l.0;

do {

b=b+r;

r=r*x/i;

i++ ;

}

while( r >= eps || r <= -eps );

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

/* Параметрический цикл */

i=2;

b=1.0;

r=х;

for( ; r >eps || г< -eps ; )

{

b=b+r;

r=r*x/i;

i=i+l;

}

Условие окончания параметрического цикла такое же, как и в цикле while.

Все три цикла записаны по возможности одинаково, чтобы подчеркнуть сходство циклов. Однако в данном примере цикл for имеет существенные преимущества. В заголовок цикла (в качестве выражения_1) можно ввести инициализацию всех переменных:

for   (i=2, b=1.0, r=x ; r>eps || r<-eps ;   )

{

b=b+r;

r=r*x/i;

i=i+l;

}

В выражение 1 можно включать операцию изменения счетчика членов ряда:

for( i=2, b=1.0, r=x ; r>eps || r<-eps ;   i++)

{

b=b+r;

r=r*x/i;

}

Можно еще более усложнить заголовок, перенеся в него все исполнимые операторы тела цикла:

for(i=2,  b=1.0, r=x ; r>eps || r<-eps; b+=r,   r*=x/i,   i++);

В данном случае тело цикла - пустой оператор. Для сокращения выражения 1 в нем использованы составные операции присваивания и операция икремента.

Задание

Вычислить выражение. Переменные вводятся с клавиатуры.

№  Варианта

Задание

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20


Порядок выполнения работы

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

Решение

Перепишем выражение  в виде

,                                                (1)

где  , ,  и т.д.

Таким образом выражение (1) можно представить в следующем виде

.                                                           (2)

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

Легко заметить, что

.

Блок-схема программы

Текст программы

#include<stdio.h>

#include <math.h>

void main()

{doublex,s,a;

inti,n;

printf("Vvtdite x-->");

scanf("%lf", &x);

printf("Vvedite n-->");

scanf("%d", &n);

s=0;

for(i=0;i<=n;i++)

{a=(i+1)*pow(x,i);

s=s+a;}

printf("RESULTAT S=%lf",s);

}

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание и исходные данные по заданному варианту работы.
  3.  Блок-схема написанной программы.
  4.  Листингпрограммы, написанный в среде программирования VisualStudio 2005.
  5.  Скриншот результата работы программы.
  6.  Ответы на контрольные вопросы.
  7.  Вывод о проделанной работе.

Контрольные вопросы

  1.  Что такое итерация? Смысл её применения при написании программы.
  2.  В некоторых языках программирования для априорного цикла используется структураwhile (. . .) do (. . .), а структураdo (. . .) while (. . .)для апостериорного цикла. Хотя такое решение и является элегантным, однако какие проблемы может повлечь за собой такое сходство?
  3.  Каков принцип работы алгоритма последовательного поиска?
  4.  В чём отличие оператора цикла while от оператора цикла dowhile?

Лабораторная работа №17.

Рекурсивные структуры в алгоритмах

Цель работы

Изучить рекурсивные структуры в алгоритмах

Задание для самостоятельной подготовки

  1.  Изучить особенности  построения рекурсивных структур алгоритмов [1], стр. 214-221.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

В программировании рекурсия— вызов функции (процедуры) из неё же самой, непосредственно (простая рекурсия) или через другие функции (сложная рекурсия), например, функция A вызывает функцию B, а функция B — функцию A. Количество вложенных вызовов функции или процедуры называется глубиной рекурсии.

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

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

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

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

Алгоритм быстрой сортировки является рекурсивным. Она, хоть и была разработана более 40 лет назад, является наиболее широко применяемым и одним их самых эффективных алгоритмов.

Метод основан на подходе «разделяй-и-властвуй». Общая схема такова:

  1.  из массива выбирается некоторый опорный элемент a[i],
  2.  запускается процедура разделения массива, которая перемещает все ключи, меньшие, либо равные a[i], влево от него, а все ключи, большие, либо равные a[i] – вправо, теперь массив состоит из двух подмножеств, причем левое меньше, либо равно правого,
  3.  для обоих подмассивов: если в подмассиве более двух элементов, рекурсивно запускаем для него ту же процедуру.

В конце получится полностью отсортированная последовательность.

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

Рисунок 1 - Блок схема работы рекурсивной процедуры

Задания

  1.  Составить список, состоящий из 10 элементов и заполнить его числами Фибоначчи начиная с вашего номера по журналу.
  2.  Составить список, состоящий из 10 элементов и заполнить его факториалами чисел (начиная с 1) деленными на ваш номер по журналу.
  3.   Составить список, состоящий из n элементов (где nваш номер по журналу) элементов и заполнить его по принципу: а[i]=  первые 3 элемента равны 1,2,3 соответственно.

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

Вставка элемента :

void insert(double x) {

element *temp;

temp = new element;

temp->info = x;

if (head == 0) {

head = temp;

tail = temp;

temp->next = 0;

   } else {

tail->next = temp;

temp->next = 0;

temp->pred = tail;

tail = temp;

   }

};

Удалениеэлемента :

voiddelete_el(double p) {

element *temp;

element *d;

   d = head;

while (d->info != p) {

       d = d->next;

   }

if (d == head) {

temp = head;

head = head->next;

delete temp;

   } else {

temp = d->pred;

temp->next = d->next;

delete d;

   }

};

Ввод-вывод списка :

voidscan() {

double k;

int i;

scanf("%i", &n);

for (i = 0; i < n; i++) {

scanf("%lf", &k);

insert(k);    }

};

void print() {

element *p;

   p = head;

while (p != 0) {

printf("%lf ", p->info);

       p = p->next;

   }

};

Задание №1

Описываем функциюF1 с входным параметром типа указатель на элемент. Для первого и второго элемента списка задаем значения 610 и 987 соответственно (15 и 16 член последовательности Фибоначчи).  

В  самой процедуре проверяем условие, что 2 предыдущих элемента не равны  0. Если условие выполняется, то записываем их сумму в текущий элемент, иначе вызываем F1 c параметром предыдущих элементов равных 0.

Далее запускаем F1 с параметром равным концу списка. Последовательность Фибоначчи, начиная с 15 элемента, теперь хранится в списке.

void  F1(element* f)

{  element *t1;

element *t2;

   t1=f->pred;

   t2=t1->pred;

if (t1->info==0){F1(t1);}

if (t2->info==0){F1(t2);}

f->info=t1->info+t2->info;

}

Задание №2

Для выполнения этого задания необходимо присвоить первому элементу в списке значение 1/15.

Далее опишем структуры рекурсивной функции F2.  У функции 2 входных параметра – указатель на элемент списка и число (для подсчета непосредственно факториала). Затем если предыдущий элемент списка равен 0, то вызываем F2 c параметрами предыдущее значение списка и число -1.

Последним шагом вызываем в главной функции процедуру с параметрами конец списка и 10.

Теперь в списке хранятся факториалы чисел от 1 до 10 деленные на 15.

void  F2(element* f,int k)

{

element *t=f->pred;

int u=k-1;

if (t->info==0){F2(t,u);}

f->info=t->info*k;

}

Задание №3

Описываем функциюF3 с входным параметром типа указатель на элемент. Для первого,  второго и третьего элемента списка задаем значения 1, 2 и 3 соответственно.  

В  самой функции проверяем условие, что 3 предыдущих элемента не равны  0. Если условие выполняется, то записываем их соответственно формуле  а[i]=   в текущий элемент, иначе вызываем F3 c параметром предыдущих элементов равных 0.

Далее запускаем F3 с параметром равным концу списка. Последовательность из 15 элементов теперь хранится в списке.

void  F3(element* f)

{  element *t1;

element *t2;

element *t3;

   t1=f->pred;

   t2=t1->pred;

   t3=t2->pred;

if (t3->info==0){F3(t3);}

if (t2->info==0){F3(t2);}

if (t1->info==0){F3(t1);}

f->info=(t1->info+t2->info)/(t3->info);  }

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные задания варианта.
  3.  Описание алгоритмов.
  4.  Листинг программы.
  5.  Скриншоты результатов работы программы.
  6.  Ответы на контрольные вопросы.
  7.  Выводы о проделанной работе.

Контрольные вопросы

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

Лабораторная работа № 18

«Структурное программирование»

Цель

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

Задание на самостоятельную работу

  1.  Изучить основные понятия структурного программирования [7], стр. 38-51, [8], стр. 13-44.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

В линейной программе все операторы выполняются последовательно, один за другим. Для того чтобы в зависимости от исходных данных обеспечить выполнение разных последовательностей операторов, применяются операторы ветвления if и switch. Оператор if обеспечивает передачу управления на одну из двух ветвей вычислений, а оператор switch — на одну из произвольного числа ветвей.

В программировании вообще, и в структурном в частности, широко используются циклы.Цикл — участок программы, повторяемый многократно. В C++ три взаимозаменяемых оператора цикла — whilе, dowhilе и for. При написании любого цикла надоиметь в виду, что в нем всегда явно или неявно присутствуют четыре элемента: начальные установки, тело цикла, модификация параметра цикла и проверка условия продолжения цикла (рис. 1). Начинающие чаще всего забывают про первое и/или третье.

Рисунок 1 - Блок – схема цикла

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

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

Операторы цикла в языке C++ взаимозаменяемы, но можно привести некоторые рекомендации по выбору наилучшего в каждом конкретном случае.

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

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

Оператор for предпочтительнее в большинстве остальных случаев. Однозначно — для организации циклов со счетчиками, то есть с целочисленными переменными, которые изменяют свое значение при каждом проходе цикла регулярным образом - (например, увеличиваются на 1).

Наиболее важные моменты этого лабораторного занятия

1. Выражение, стоящее в круглых скобках операторов if, while и dowhilе, вычисляется в соответствии с приоритетами операций и преобразуется к типу bool.

2. Если в какой-либо ветви вычислений условного оператора или в цикле тре-буется выполнить более одного оператора, то они объединяются в блок.

3. Проверка вещественных величин на равенство опасна.

4. Чтобы получить максимальную читаемость и простоту структуры программы, надо правильно выбирать способ реализации ветвлений (с помощью if, switch или условной операции), а также наиболее подходящий оператор цикла.

5. Выражение, стоящее в скобках после ключевого слова switch, и константные выражения в case должны быть целочисленного типа.

6. Рекомендуется всегда описывать в операторе switch ветвь default.

7. После каждой ветви для передачи управления на конец оператора switch используется оператор break.

8. При написании любого цикла надо иметь в виду, что в нем всегда явно или неявно присутствуют четыре элемента: начальные установки, тело цикла, мо-дификация параметра цикла и проверка условия продолжения цикла.

9. Если количество повторений цикла заранее не известно, необходимо предусматривать аварийный выход из цикла по достижении некоторого достаточно большого количества итераций.

Теорема Бёма — Якопини — положение структурного программирования, согласно которому любой исполняемый алгоритм может быть преобразован к структурированному виду, то есть такому виду, когда ход его выполнения определяется только при помощи трёх структур управления: последовательной (англ. sequence), ветвлений (англ. selection) и повторов или циклов.

Задание

Вариант 1

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а,b,с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) И (Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 2

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а,b,с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИВц) ИЛИ (Вц И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сд обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 3

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

Ац И (Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 4

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

Ац ИЛИ Вц ИЛИ Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операция ИЛИ — поразрядная. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 5

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) И Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 6

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИВц) ИЛИ (Ац И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 7

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) МОД2 (Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 8

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, Ь, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2 Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 9

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И (Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 10

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 11

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИВц) МОД2 Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 12

Вычислив и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) И Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 13

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) МОД2 (Вц ИСц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 14

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа

Функция F должна принимать действительное значение, если выражение (Ац МОД2Вц) ИЛИ (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сцобозначены целые части значений а, b, с, операции ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 15

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 16

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2 Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 17

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 18

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИВц И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ иИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 19

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где a, b,c,dдействительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2Вц) ИЛИ (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, d, Хнач., Хкон., dX ввести с клавиатуры.

Вариант 20

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.

Порядок выполнения работы

Задача. Вычисление значения функции, заданной аналитически.

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

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

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

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

1. Ввести значение аргумента х.

2. Определить, какому интервалу из области определения функции оно принадлежит.

3. Вычислить значение функции у по соответствующей формуле.

4. Вывести значение у.

Детализировать этот алгоритм уже практически некуда, поэтому сразу же смело напишем первый вариант программы:

#include <iostream.h>

int main()

{

float x, у;

cout<<«Введите значение аргумента»<<endl;

cin>> х;

if( х < -2 )       у = 0;

if ( х >= -2 && х < -1 ) у = -х – 2;

if( х >= -1 && х < 1 ) у = х;

if ( х >= 1 && х < 2 ) у = -х + 2;

if( х >= 2 )       у = 0;

cout<<« Для х = «<< х <<« значение функции у = «<< у <<endl;

return 0;

}

Тестовые примеры для этой программы должны включать по крайней мере по одному значению аргумента из каждого интервала, а для проверки граничных уcловий — еще и все точки перегиба (если это кажется вам излишним, попробуйте в последнем условии «забыть» знак =, а затем ввести значение х, равное 2).

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

Операции отношения (<, >, = =, <, >, !=) являются бинарными, то есть имеют два операнда, и формируют результат типа bool, равный true или false (В компиляторах, не поддерживающих тип bool, истинным считается любое значение, не равное нулю). Поскольку необходимо, чтобы эти условия выполнялись одновременно, они объединены с помощью операции логического И (&&) — не путать с поразрядным И! Приоритет у операции И ниже, чем у операций отношения, поэтому заключать их в скобки не требуется.

Весьма распространенная ошибка начинающих — запись подобных условий в виде кальки с математической формулы, то есть, как а < b < с. Синтаксической ошибки в этом выражении нет, поэтому компилятор не выдает каких-либо сообщений. Давайте посмотрим, что же происходит при вычислении. Операции отношения одного приоритета выполняются слева направо, поэтому сначала будет выполнена операция а < b и сформирован результат в виде true или false. Следующая операция будет выглядеть как true< c или false< c. Для ее выполнения значения true и false преобразуются соответственно в единицу и ноль того же типа, что и с, и формируется результат, смысл которого вряд ли соответствует ожиданиям.

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

if(х<= -2)          у = 0;

elseif (х< -1)    у = -х - 2;

elseif (х<  1)    у = х;

elseif (х< 2)     у = -х + 2;

else                   у = 0;

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

y = 0;

if ( х > -2 )   у = -х - 2;

if( х > -1 )   у = х;

if ( х >   1 )  у = -х + 2;

if( х > 2 )    у = 0;

Запись фрагмента стала еще короче, но появились два недостатка: значение функции вычисляется многократно (от двух до пяти раз в зависимости от интервала, которому принадлежит х), значит, увеличилось время выполнения, а главное — программа потеряла универсальность, то есть таким способом можно вычислить не всякую функцию. Для того чтобы в этом убедиться, попробуйте заменить у = х на, к примеру, фрагмент окружности y=sqrt(l-x*x) и ввести значение х, большее 1 — это приведет к ошибке в программе, связанной с вычислением квадратного корня из отрицательной величины.

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

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

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

В заключение приведем вариант с использованием функций ввода-вывода в стиле С:

#include <stdio.h>

int main()

{float x, у;

printf(“Введите значение аргумента:\n");

scanf("%f", &x);

if ( x < -2 )                       у = 0;

if( x >= -2 && x < -1)      у = -x – 2;

if( x >= -1 && x < 1)       у = x;

if( x >=  1 && x < 2)        у = -x + 2;

if( x >=  2)                      у = 0;

printf(“Для x = %5.2f значение функции у = %5.2f\n", x, у);

return 0;

}

Отчет о работе

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные задания.
  3.  Листинг программы.
  4.  Результат работы программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что такое «Структурное программирование»?
  2.  Какие существуют конструкции структурного программирования?
  3.  Какую структуру имеет программа?
  4.  Какие операторы служат для организации разветвляющихся программ и организации циклов?
  5.  В чем суть теоремы Бома-Якопини?

Лабораторная работа № 19.

Программные модули в языках программирования

Цель

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

Задание на самостоятельную работу

  1.  Изучить основные понятия модульного программирования [7], стр. 72-101, [8], стр. 150-154.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

С увеличением объема программы становится невозможным удерживать в памяти все детали. Естественным способом борьбы со сложностью любой задачиявляется ее разбиение на части. В C++ задача может быть разделена на болеепростые и обозримые с помощью функций, после чего программу можно рассматривать в более укрупненном виде — на уровне взаимодействия функций. Этоважно, поскольку человек способен помнить ограниченное количество фактов.Использование функций является первым шагом к повышению степени абстракции программы и ведет к упрощению ее структуры.

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

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

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

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

Модульность в языке C++ поддерживается с помощью директив препроцессора, пространств имен, классов памяти, исключений и раздельной компиляции (строго говоря, раздельная компиляция не является элементом языка, а относится к его реализации).

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

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

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

Таким образом, заголовочный файл xxx.hсодержитинтерфейсдля некоторого набора функций, а исходный файл ххх.срр содержитреализацию этого набора. Если некоторая функция из указанного набора вызывается из какого-то другого исходного модуля ууу.срр, то вы обязаны включить в этот модуль заголовочный файл ххх.hс помощью директивы include. Негласное правило стиля программирования на C++ требует включения этого же заголовочного файла (с помощью #include) и висходный файл ххх.срр.

В многофайловом проекте возможны два «вида глобальности». Если некоторая глобальная переменная glvarlобъявлена в файле ххх.срр с модификатором static, то она видима от точки определения до конца этого файла, то есть область ее видимости ограничена файлом. Если же другая глобальная переменная glvar2 объявлена в файле ххх.cppбез модификатора static, то она может быть видимой в пределах всего проекта. Правда, для того, чтобы она оказалась видимой в другом файле, необходимо иметь в этом файле ее объявление с модификатором extern(рекомендуется это объявление поместить вфайл xxx.h).

Что и как следует размещать в заголовочном файле?

В заголовочном файле принято размешать:

  •  определения типов, задаваемых пользователем, констант, шаблонов;
    •  объявления (прототипы)функций;
    •  объявления внешних глобальных переменных (с модификатором extern);
    •  пространства имен.

Теперь обратим ваше внимание на проблему повторного включения заголовочных файлов. Проблема может возникнуть при иерархическом проектировании структур данных, когда в некоторый заголовочный файл ууу.hвключается при помощи директивы #tncludeдругой заголовочный файл xxx.h(например, для использования типов, определенных в этом файле).

Задание

Вариант 1

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры. Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 2

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где a, b,c,dдействительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2Вц) ИЛИ (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, d, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 3

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИВц И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ иИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 4

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 5

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2 Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 6

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 7

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа

Функция F должна принимать действительное значение, если выражение (Ац МОД2Вц) ИЛИ (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 8

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) МОД2 (Вц ИСц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 9

Вычислив и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) И Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 10

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИВц) МОД2 Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 11

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И (Ац МОД2 Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 12

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

НЕ(Ац ИЛИ Вц) И (Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции НЕ, И и ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 13

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, Ь, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац МОД2 Вц) И НЕ(Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 14

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) МОД2 (Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции И, ИЛИ и МОД2 (сложение по модулю 2) — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 15

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИВц) ИЛИ (Ац И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 16

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) И Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 17

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

Ац ИЛИ Вц ИЛИ Сц

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операция ИЛИ — поразрядная. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 18

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а, b, с — действительные числа.

Функция F должна принимать действительное значение, если выражение

Ац И (Вц ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 19

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а,b,с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИВц) ИЛИ (Вц И Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сд обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Вариант 20

Вычислить и вывести на экран в виде таблицы значения функции F на интервале от Хнач. до Хкон. с шагом dX.

где а,b,с — действительные числа.

Функция F должна принимать действительное значение, если выражение

(Ац ИЛИ Вц) И (Ац ИЛИ Сц)

не равно нулю, и целое значение в противном случае. Через Ац, Вц и Сц обозначены целые части значений а, b, с, операции Ии ИЛИ — поразрядные. Значения а, b, с, Хнач., Хкон., dX ввести с клавиатуры.Расчет по каждой формуле оформить в виде отдельного модуля программы.

Порядок выполнения работы

Ниже приведен листингпростой многофайловой программы, в которой определены типы данных «Точка» (структура Pointв файле Point.h) и «Прямоугольник» (структура Rectв файле Rect.h). Поскольку второй тип данных определяется через первый, вфайле Rect.hимеетсядиректива#include«Point.h». В основном модуле main.cppпросто создается объект типа «Прямоугольник» и выводятся координаты его левого верхнего и правого нижнего углов. В основном модуле используются как функции из модуля Point.срр. так и функции из модуля Rect.cpp. поэтому в него включены оба заголовочных файла Point.hи Rect.h. Но после обработки этих директив препроцессором окажется, что структура Pointопределена дважды. В результате компилятор выдаст сообщение об ошибке наподобие следующего: «error...; 'Point'; 'struct* typeredefinition».

/////////   Файл Point.h//////////

// Объявления типов

structPoint

{

ititx;

inty;

};

// Прототипыфункций

voidSetXY(Point& point, int x. int y>;

intGetX(Point& point);

intGetY(Point& point);

//////////   ФайлRect.h   ////////////

♦include “Point.h”

// Объявлениятипов

structRect

{

Point leftTop;

Point rightBottom;

};

// Прототипыфункций

voidSetLTRB(Rect&rect, Point lt, Point rb);

voidGetLT(Rect&rect, Point&lt);

voidGetRB(Rect&rect, Point&rb);

//////////   Файл Point.cpp   ///////////

#include “Poin.h”

voidSetXY(Poin& point, int x, int y)

{

point.x=x;

poin.y=y;

}

intGetX(Point& point)

{

returnpoint.x;

}

intGetY(Point& point)

{

return point.у;

}

///////////   Файл Rect.cpp   ///////////

#include “Rect.h”

voidSetLTRB(Rect&rect, Point lt. Point rb)

{

rect. leftTop = lt;

rect.rightBottom = rb;

}

voidGetLT(Rect& rect. Point&lt)

{

lt = rect.leftTop;

}

voidGetRB(Rect&rect, Point&rb)

{

rb = rect.rightBottom;

}

#include <stdio.h>

#include “Point.h”

#include “Rect.h”

///////////////   ФайлMain.cpp   //////////////

int main()

{

Point ptl, pt2, lt. rb;

Rectrectl;

SetXV(ptl, 2, 5);

SetXY(pt2, 10, 14);

SetLTRB(rect1, ptl, pt2);

GetLT(rect1, lt);

GetRB(rect1, rb);

printf(“rect.lt.x = %d, rect.lt.y = %d\n, lt.x, lt.y);

printf(“rect.rb.x = %d, rect.rb.y = %d\n”, rb.x, rb.y);

return0;

}

Каков выход из этой ситуации? Бьерн Страуструп рекомендует использовать так называемые стражи включения, и этот способ нашел широкое применение. Он состоит в следующем: чтобы предотвратить повторное включение заголовочных файлов, содержимое каждого h-файла должно находиться между директивамиусловной компиляции #ifndefи #endif, как описано ниже:

#ifndef FILENAME_H

#define FILENAME_H

/* содержимое заголовочного файла */

#endif/* FILFNAME_H*/

Применительно к нашему примеру файл Point.hдолжеч содержать следующий текст:

////////////   ФайлPoint.h   ///////////////

#ifndef P0INT_H

#define POINT_H

// Объявлениятипов

struct Point

{int x;

inty;

};//Прототипыфункций

voidSetXY(Point& point,int x, int y);

intGetX(Point& point);

intGetV(Point&point);

#endif/*P0INT_H*/

Отчет о работе

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные задания.
  3.  Листинг программы.
  4.  Результат работы программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что включает понятие «Модульное программирование»?
  2.  Что содержит модуль?
  3.  Какую функцию выполняет заголовочный файл и что включается в его состав?
  4.  С какой целью осуществляется инкапсуляция и чем она достигается?
  5.  Как поддерживается модульность в программировании?

Лабораторная работа № 20.

Технология объектно-ориентированного программирования

Цель

Изучить специализированные типы данных в объектно-ориентированном программировании

Задание на самостоятельную подготовку

  1.  Изучить основные понятия и организацию класса как типа данных в объектно – ориентированном программировании [7], стр. 178-200 [9], стр. 12-58.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Класс является одним из основных понятий в объектно-ориентированном программировании.

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

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

Основными свойствами ООП являются инкапсуляция, наследование и полиморфизм. Ниже кратко поясняется их смысл.

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

Наследование — это возможность создания иерархии классов, когда потомки наследуют все свойства своих предков, могут их изменять и добавлять новые. Свойства при наследовании повторно не описываются, что сокращает объем программы. Иерархия классов представляется в виде древовидной структуры, в которой более общие классы располагаются ближе к корню, а более специализированные — на ветвях и листьях. В C++ каждый класс может иметь сколько угодно потомков и предков.

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

Благодаря тому, что программа представляется в терминах поведения объектов, при программировании используются понятия, более близкие к предметной области, следовательно, программа легче читается и понимается. Это является большим преимуществом ООП. Класс является абстрактным типом данных, определяемым пользователем, и представляет собой модель реального объекта в виде данных и функций для работы с ними.

Данные класса называются полями (по аналогии с полями структуры), а функции класса — методами. Поля и методы называются элементами класса. Описание класса в первом приближении выглядит так:

class<имя>

{

[ private:]

<описание скрытых элементов>

public:

<описание доступных элементов>

}; // Описание заканчивается точкой с запятой

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

Поля класса:

  •  могут иметь любой тип, кроме типа этого же класса (но могут быть указателями или ссылками на этот класс);
  •  могут быть описаны с модификатором const, при этом они инициализируются только один раз и не могут изменяться;
  •  могут быть описаны с модификатором static, но не как auto, extern и register.

Инициализация полей при описании не допускается.

Классы могут быть глобальными (объявленными вне любого блока) и локальными (объявленными внутри блока, например, функции или другого класса).

Ниже перечислены некоторые особенности локального класса:

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

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

classmonstr

{

int health, ammo:

public:

monstr(int he = 100, int am = 10)

{health = he; ammo = am;

}

void draw(int x, int y, int scale, int position):

intget_health()

{

return health;

}

intget_ammo(){returnammo;

}

};

В этом классе два скрытых поля — health и ammo, получить значения которых извне можно с помощью методов get_health() и get_ammo(). Доступ к полям с помощью методов в данном случае кажется искусственным усложнением, но надо учитывать, что полями реальных классов могут быть сложные динамические структуры, и получение значений их элементов не так тривиально. Кроме того, очень важной является возможность вносить в эти структуры изменения, не затрагивая интерфейс класса.

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

В приведенном классе содержится три определения методов и одно объявление (метод draw). Если тело метода определено внутри класса, он является встроенным (inline). Как правило, встроенными делают короткие методы. Если внутри класса записано только объявление (заголовок) метода, сам метод должен быть определен в другом месте программы с помощью операции доступа к области видимости (::):

voidmonstr::draw(int x, int у, int scale,  int position){ /* телометода */

} Метод можно определить как встроенный и вне класса с помощью директивы inline(как и для обычных функций, она носит рекомендательный характер):

inlineintmonstr::get_ammo(){ returnammo;} В каждом классе есть хотя бы один метод, имя которого совпадает с именем класса. Он называется конструктором и вызывается автоматически при создании объекта класса. Конструктор предназначен для инициализации объекта. Автоматический вызов конструктора позволяет избежать ошибок, связанных с использованием неинициализированных переменных. Типы данных struct и union являются видами класса.

Конкретные переменные типа «класс» называются экземплярами класса, или объектами. Время жизни и видимость объектов зависит от вида и места их описания и подчиняется общим правилам C++:

monstrVasia; // Объект класса monstr с параметрами по умолчанию

monstrSuper(200, 300): // Объект с явной инициализацией

monstrstado[100]:// Массив объектов с параметрами по умолчанию

monstr *beavis = new monstr (10);   // Динамическийобъект

//(второй параметр задается по умолчанию)

monstr&butthead = Vasia;     // Ссылка на объект

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

Доступ к элементам объекта аналогичен доступу к полям структуры. Для этого используются операция . (точка) при обращении к элементу через имя объекта и операция -> при обращении через указатель, например:

int n = Vasia.get_ammo();

stado[5].draw;

cout<<beavis->get_health();

Обратиться таким образом можно только к элементам со спецификатором publiс. Получить или изменить значения элементов со спецификатором private можно только через обращение к соответствующим методам.

Можно создать константный объект, значения полей которого изменять запрещается. К нему должны применяться только константные методы:

classmonstr

{

intget_health() const {return health;}

}:

constmonstr Dead(0,0);   // Константныйобъект

cout<<Dead.get_health();

Константныйметод:

  •  объявляется с ключевым словом const после списка параметров;
  •  не может изменять значения полей класса;
  •  может вызывать только константные методы;
  •  может вызываться для любых (не только константных) объектов.

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

Задание

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

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

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

4. Описать класс для работы с цепными списками строк (строки произвольной длины) с операциями включения в список, удаления из списка элемента с заданным значением данного, удаления всего списка или конца списка, начиная с заданного элемента.

5. Описать класс для объектов-векторов, задаваемых координатами концов в трехмерном пространстве. Обеспечить операции сложения и вычитания векторов с получением нового вектора (суммы или разности), вычисления скалярного произведения двух векторов, длины вектора, косинуса угла между векторами.

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

7. Описать класс для определения одномерных массивов целых чисел (векторов). Предусмотреть возможность обращения к отдельному элементу массива с контролем выхода за пределы индексов, возможность задания произвольных границ индексов при создании объекта и выполнения операций поэлементного сложения и вычитания массивов с одинаковыми границами индексов, умножения и деления всех элементов массива на скаляр, печати (вывода на экран) элементов массива по индексам и всего массива.

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

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

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

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

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

12. Описать класс «домашняя библиотека». Предусмотреть возможность работы с произвольным числом книг, поиска книги по какому-либо признаку (например, по автору или по году издания), добавления книг в библиотеку, удаления книг из нее, сортировки книг по разным полям.

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

13. Описать класс «записная книжка». Предусмотреть возможность работы с произвольным числом записей, поиска записи по какому-либо признаку (например, по фамилии, дате рождения или номеру телефона), добавления и удаления записей, сортировки по разным полям.

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

14. Описать класс «студенческая группа». Предусмотреть возможность работы с переменным числом студентов, поиска студента по какому-либо признаку (например, по фамилии, дате рождения или номеру телефона), добавления и удаления записей, сортировки по разным полям.

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

15. Описать класс «множество», позволяющий выполнять основные операции — добавление и удаление элемента, пересечение, объединение и разность множеств.

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

16. Описать класс «предметный указатель». Каждый компонент указателя содержит слово и номера страниц, на которых это слово встречается. Количество номеров страниц, относящихся к одному слову, от одного до десяти. Предусмотреть возможность формирования указателя с клавиатуры и из файла, вывода указателя, вывода номеров страниц для заданного слова, удаления элемента из указателя.

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

17. Описать класс, реализующий стек. Написать программу, использующую этот класс для отыскания прохода по лабиринту.

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

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

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

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

19. Описать класс, реализующий тип данных «вещественная матрица» и работу с ними. Класс должен реализовывать следующие операции над матрицами:

  •  сложение, вычитание, умножение, деление (+, -, *, /) (умножение и деление, как на другую матрицу, так и на число);
  •  операции сравнения на равенство/неравенство;
  •  методы вычисления детерминанта;
  •  методы, реализующие проверку типа матрицы (квадратная, диагональная, нулевая, единичная, симметрическая, верхняя треугольная, нижняя треугольная);
  •  операция ввода/вывода в стандартные потоки.

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

20. Описать класс позволяющий выполнятьследующие операции над обыкновенными дробями видаP/Q(P— целое,Q— натуральное):

  •  сложение;
  •  вычитание;
  •  умножение;
  •  деление;
  •  сокращение дроби.

Порядок выполнения работы

Рассмотрим в качестве примера описание класса принтеров. Включим в его состав следующие свойства: модель, год выпуска и состояние принтера; спрячем эти свойства от постороннего воздействия, поместив в разделprivate. Ограничимся двумя возможными состояниями принтера: 0–принтер готов к работе, 1– принтер печатает. Методы сделаем доступными для других объектов.

Методinit_printer()позволит установить начальные значения свойствам принтера. Методset_print()переведет принтер в состояние печати, если принтер до того находился в состоянии готовности, и не изменит его состояния, если принтер уже печатал. Методstop_print()приводит к остановке печати.

Методshow()отображает состояние принтера на экране:

classPrinter

{

private:

char model[15];//модельпринтера

intyear;//год выпуска

intstatus;//состояние принтера

public:

void init_printer(char* _model, int _year);

voidset_print();

voidstop_print();

voidshow();

};

Замечание.Если раздел private включен в объявлении класса первым, ключевое слово private можно опустить:

class Printer

{

charmodel[15];//модельпринтера

int year;//год выпуска

int status;//состояние принтера

public:

void init_printer(char*_model,int_year);

voidset_print();

voidstop_print();

void show();

};

Описаниеметодов:

void Printer::init_printer(char* _model,int _year)

{

strcpy(model,_model); //инициализациясвойства model

year=_year;//инициализация свойстваyear

status=0;//начальное состояние – готов к печати

}

void Printer :: set_print()

{

if(!status) status=1;

}

void Printer :: stop_print()

{

status=0;

}

void Printer :: show()

{

cout<<"Model:"<<model<<"year:"<<year<<"status:"<<status<<endl;

}

В главную часть программы– функциюmain()– включим следующие действия: создание объекта, инициализация свойств объекта, изменение состояния объекта и вывод его текущего состояния на экран:

int main(void)

{

Printerprinter;//созданиеобъекта

//инициализация свойств объекта

printer.init_printer("HP5P",1999);

printer.show();//вызовметодаобъекта

printer.set_print();

printer.show();

printer.set_print();

printer.show();

printer.stop_print();

printer.show();

return0;

}

В результате работы программы на экране появятся 4 строки текста:

Model: HP5P year: 1999 status: 0,

Model: HP5P year: 1999 status: 1,

Model: HP5P year: 1999 status: 1,

Model: HP5P year: 1999 status: 0.

Отчет о работе

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные задания.
  3.  Листинг программы.
  4.  Результат работы программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что такое класс?
  2.  В чем состоит различие между классом и объектом?
  3.  Предположим, что классы PartTimeEmployeeи FullTimeEmployeeнаследуют свойства класса Employee. Какими характеристиками будут обладать эти классы?
  4.  Что такое интерфейс класса?
  5.  Что такое наследование?
  6.  Что такое полиморфизм?
  7.  Что такое инкапсуляция?

Лабораторная работа № 21.

Последовательные списки

Цель работы

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

Задание для самостоятельной подготовки

  1.  Изучить основы организации данных в виде последовательных списков на языке программирования С++[1], стр. 337-343, [7], стр. 115-119.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

Рисунок 1 – Упорядоченный по возрастанию последовательный список

Реализация последовательных списков с использованием массивов

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

Эта задача может быть реализована на языке Си++ с помощью следующего программного кода:

#include<iostream>

usingnamespace std;

intmain()

{

const int n=20;   // количество элементов массива

int b[n];              // описание массива

int i;

for(i=0; i<n; i++) cin >> b[i];  // вводмассива

for(i=0; i<n-1; i++)                // n-1 раз поиск наименьшего элемента

{

// принимаем за наименьший первый из рассматриваемых элементов

int imin=i;

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

for(int j=i+1; j<n; j++)

// если нашли меньший элемент, запоминаем его номер

if(b[j]< b[imin]) imin=j;

int a=b[i];     // обмен элементов

b[i]=b[imin]; // с номерами

b[imin]=a;    // i и imin

}

// вывод упорядоченного массива

for(i=0; i<n; i++)cout << b[i] <<' ';

return 0;

}

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

Алгоритм сортировки целочисленного массива состоит в том, что выбирается наименьший элемент массива и меняется местами с первым элементом. Далее, рассматриваются элементы, начиная со второго, и наименьший из них меняется местами со вторым элементом, так далее n-1 раз. При последнем проходе цикла при необходимости меняются местами предпоследний и последний элементы массива.

Процесс обмена элементов массива с номерами i и imin через буферную переменную a на i-м проходе показан на рис.2. Цифры около стрелок обозначают порядок действий.

Рисунок 2- Обмен значений двух переменных

Ввод и вывод целых чисел (элементов одномерного массива) осуществляется с использованием стандартных потоков (cin и cout) и операций (>> и <<) ввода-вывода языка программирования Си++.

Более сложный пример хранения данных в памяти компьютера представляет собой хранение списка из десяти имен, каждое из которых не длиннее восьми символов. В таком случае программист может создать непрерывный список в виде двумерного массива символов, состоящего из десяти строк и восьми столбцов, размещение которого в непрерывном блоке оперативной памяти показано на рис. 3 (предполагается, что массив хранится построчно). Такая организация данных также называется последовательным (непрерывным) списком. Из рисунка видно, что большой блок ячеек памяти разделен на подблоки, содержащие по восемь ячеек. В каждом подблоке хранится имя, записанное в кодах ASCII, и для хранения каждой буквы используется одна ячейка. Если длины имени не хватает для заполнения всех ячеек в выделенном для него подблоке, оставшиеся ячейки можно заполнить кодом ASCII для пробела. Этот подход требует 80 последовательных ячеек памяти для хранения списка из 10 имен.

Рисунок 3 – Имена, хранящиеся в памяти в виде непрерывного списка

Эта задача реализуется на языке Си++ с помощью следующего программного кода:

#include<iostream>

usingnamespace std;

int main()

{

constint n=10, m=8; //

char Name[n][m]; //

int i,j;

// Вводзаписейсписка

cout <<"Vvedite spisok\n\n";

for(i=0; i<n; i++) //

for(j=0; j<m; j++) cin >> Name[i][j];

cout <<"\n";

// Выводсписка

for(i=0; i<n; i++)

{

for(j=0; j<m; j++) cout << Name[i][j];

cout <<"\n";

}

return 0;

}

В данной программе вводится с клавиатуры список из десяти фамилий, а затем осуществляется его вывод на экран монитора. Элементы массива имеют символьный тип данных char. Тип элементов массива вместе с его размерностью определяет объем памяти, необходимый для размещения массива, которое определяется на этапе компиляции программы. Поэтому выбор типа данных для хранения списка программист должен осуществлять продуманно. Например, если список представляет собой последовательность только цифр, то в этом случае целесообразно использовать для элементов массива int, float или double в зависимости от величины элементов списка. При этом, если хотя бы один элемент будет иметь тип который требует для своего хранения большее количество байт, чем остальные элементы списка, то тип именно этого элемента и будет определять тип данных массива. Например, один элемент списка (3.14) имеет тип float, а все остальные элементы списка (1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) имеют тип int. Следовательно, в качестве типа данных для массива следует выбрать тип float. После ввода каждого элемента строки следует нажимать клавишу пробела, а после ввода последнего элемента клавишу ввода. При таком способе ввода расположение элементов массива на экране монитора будет аналогично концептуальному представлению списка.

В случае, если в списке имеется хотя бы один символ, не являющийся цифрой (какая либо буква, символы @, # и т.п.), то для элементов массива следует использовать символьный тип char или расширенный символьный тип wchar_t (в случае если для кодировки недостаточно одного байта). При этом следует помнить, что в этом случае каждому элементу массива будет соответствовать только один введенный символ. Любая последовательность символов введенных подряд (без пробелов), например 1A#B ,будет восприниматься компилятором как инициализация четырех элементов массива. Символы, превышающие количество элементов массива игнорируются.

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

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

Описание нового типа данных - структуры (неоднородного массива) на языке Си++ может выглядеть так:

StructStudent  // Описание структуры с именем «Студент»

{

Описание полей (элементов) структуры

charName [20], Faculty [30], Speciality [50];

int Course, Mathematics, Physics, Computer science;

};

Имя нового типа данных – Student. Можно описать переменные этого типа точно так же, как и переменные встроенных типов, например:

Studentst1, st2[10].

В данной строке описываются:

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

Рисунок 4 - Структура, хранящаяся в памяти в виде непрерывного блока

  •  массив структур st2[10], то есть массив, элементами которого являются десять структур, каждая из которых в свою очередь состоит из семи полей различного типа.

Рисунок 5 – Массив структур, хранящийся в памяти в виде непрерывного блока

Задания

  1.  Дана строка длиной n (где n ваш номер по журналу + 20). Вывести ее на экран в противоположном порядке. Для решения данной задачи используйте двусвязные списки. Пример: ввод: «мама» ; вывод: «амам».
  2.  Пусть заданы линейные списки: список элементов В=<К1,К2,К3,...,Кn> и список ключей V= (целые числа, делящиеся на номер вашего варианта по журналу). Требуется для каждого значения Vi из V найти множество всех совпадающих с ним элементов из В.

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные задания варианта.
  3.  Описание использованных алгоритмов.
  4.  Листинг программы.
  5.  Скриншоты результатов работы программы.
  6.  Ответы на контрольные вопросы
  7.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Дайте понятие последовательного списка.
  2.  В каких случаях список считается упорядоченным? Является ли упорядоченной следующая числовая последовательность: 7720560445?
  3.  Укажите различия между одномерным, двумерным массивом и структурой, как способами организации данных.
  4.  Как можно произвести сортировку списка по возрастанию?
  5.  Как можно определить объем памяти, необходимый для размещения списка?
  6.  В чем принципиальные отличия выполнения основных операций в однонаправленных и двунаправленных списках?
  7.  С какой целью в программах выполняется проверка на пустоту однонаправленного (двунаправленного) списка?
  8.  С какой целью в программах выполняется удаление однонаправленного (двунаправленного) списка по окончании работы с ним? Как изменится работа программы, если операцию удаления списка не выполнять?

Лабораторная работа № 22.

Связанные списки

Цель

Формирование навыков организации данных в виде связанных списков на языке программирования высокого уровня.

Задание для самостоятельной подготовки

  1.  Изучить основы организации данных в видесвязанных списков на языке программирования С++[1], стр. 337-343, [2], стр.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

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

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

Элементы удаляются из цепи разрывом двух соединений, удалением звена и затем повторным соединением цепи.

Применительно к связанным спискам данная модель будет представлять совокупность связанных узлов. Узел (Node) состоит из поля данных (item) и указателя (next), обозначающего следующий элемент в списке. Указатель — это соединитель, связывающий вместе отдельные узлы списка. Связанный список состоит из множества узлов, первый элемент которого (front), — это узел, на который указывает голова (head). Список связывает узлы вместе от первого до конца или хвоста (rear) списка. Хвост определяется как узел, чье поле указателя имеет значение NULL (0). Списочные приложения проходят по узлам, следуя за каждым указателем на следующий узел. В любой точке сканирования на текущее положение ссылается указатель currPtr. Для списка без узлов head будет содержать значение NULL.

На рисунке 1 приведена структура односвязного списка. На нем поле INF - информационное поле, данные, NEXT - указатель на следующий элемент списка. Каждый список должен иметь особый элемент, называемый указателем начала списка или головой списка, который обычно по формату отличен от остальных элементов. В поле указателя последнего элемента списка находится специальный признак nil, свидетельствующий о конце списка.

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

Однако, обработка односвязного списка не всегда удобна, так как отсутствует возможность продвижения в противоположную сторону. Такую возможность обеспечивает двухсвязный список, каждый элемент которого содержит два указателя: на следующий и предыдущий элементы списка. Структура линейного двухсвязного списка приведена на рисунке 2, где поле NEXT - указатель на следующий элемент, поле PREV - указатель на предыдущий элемент. В крайних элементах соответствующие указатели должны содержать nil, как и показано на рисунке 3:

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

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

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

Рисунок 3 – Структура кольцевого списка

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

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

Алгоритмы связанных списков реализуются как независимые функции, чтобы изменения в одной функции не повлияли на поведение другой. Для этого все, что функциям необходимо получить извне, должно передаваться им через параметры. Все параметры, не изменяемые внутри функции, должны передаваться им с модификатором const. Указатели, которые могут измениться (например, при удалении из списка последнего элемента указатель на конец списка требуется скорректировать), передаются по адресу.

#include <iostream.h>

#include <stdlib.h>

struct Node

{

 int data;

 Node *link;

 };

// создание узла (используется функциями Insert)

Node *GetNode(int item, Node *nextPtr);

// функциивставкиузла

voidInsertFront(Node* & head, int item);

voidInsertEnd(Node* &head, int item);

voidInsertOrder(Node* &head, int item);

// удаление узла

voidDeleteFront(Node* &head);

void Delete(Node* &head, int key);

// печать списка

voidPrintList(Node *head);

// очистка списка

voidClearList(Node* &head);

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

Связанный список начинается с указателя узла, который ссылается на начало списка. Такой указатель называется головой, так как он указывает на начало списка. Первоначально значением головы является NULL для указания пустого списка.

Node *head = NULL;

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

ПРИМЕР

...

intmain()

{

 Node *head = NULL;   // объявление и инициализация

     // головы списка

 InsertFront(head, 12);  // вставка 12 в голову списка

 InsertFront(head, 8);  // вставка 8 в голову списка

 PrintList(head);   // печатает 8 и 12

DeleteFront(head);  // удаляет 8

 InsertEnd(head, 15); // вставка 15 в конец списка

 PrintList(head);  // печатает 12 и 15

...

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

// выделение узла с данным-членомitem и указателем nextPtr

Node *GetNode(int item, Node *nextPtr = NULL)

{

 Node *newNode;

//выделение памяти при передаче item и NextPtr конструктору

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

 newNode = new Node;

if (newNode == NULL)

 {

 cerr<< "Ошибка выделения памяти!" <<endl;

 exit(1);

}

newNode->data = item;

newNode->link = nextPtr;

 returnnewNode;

}

Вставка узла в начало списка. Реализуется с помощью функции InsertFront. Операция вставки узла в начало списка требует обновления значения указателя головы, так как список должен теперь иметь новое начало. Проблема сохранения головы списка является основной для управления списками. Если голова потеряется, то потеряется и список!

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

head = GetNode(item,head);

Рисунок 4 – Вставка узла в начало списка

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

// вставка элемента в начало списка

voidInsertFront(Node* &head, intitem)

{

// создание нового узла, чтобы он указывал на

// первоначальную голову списка, изменение головы списка

head = GetNode(item,head);

}

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

currPtr = head;

Для печати значений каждого узла во время прохождения списка используется оператор cout:

cout<<currPtr->data;

В процессе сканирования currPtrнепрерывно перемещаетсяк следующему узлу до тех пор, пока не будетдостигнут конец списка.

currPtr = currPtr->nextNode();

Прохождение по списку завершается, когда currPtr становится равным NULL. Например, функция PrintList печатает значение данных каждого узла. Голова передается в качестве параметра для определения списка.

// печать связанного списка

voidPrintList(Node *head)

{

// currPtr пробегает по списку, начиная с головы

Node *currPtr = head;

// пока не конец списка, печатать значение данных

 // текущегоузла

while(currPtr != NULL)

 {

 cout<<currPtr->data<<endl;

 // перейти к следующему узлу

 currPtr = currPtr->link;

}

}

Вставка узла в конец списка. Операция реализуется функцией InsertEnd. Помещение узла в хвост списка требует начального тестирования для определения, пуст ли список. Если да, то узел вставляетсяв начало списка с помощью функции InsertFront. При непустом списке необходимо сканировать узлы для обнаружения хвостового узла (в котором поле link содержит значение NULL).

currPtr->link == NULL;

Рисунок 5 – Вставка узла в конец списка

Затем с помощью функции GetNode создается новый узел newNode и, наконец, он вставляется после текущего объекта.

newNode->link = currPtr->link;

currPtr->link = newNode;

Так как вставка может изменять значение указателя головы, голова передается как ссылочный параметр:

// найти хвост списка и добавить item

voidInsertEnd(Node* & head, int item)

{

 Node *newNode, *currPtr = head;

// если список пуст, вставить item в начало

 if (currPtr == NULL)

 InsertFront(head,item);

else

{

 // найти узел с нулевым указателем

 while(currPtr->link != NULL)

  currPtr = currPtr->link;

 // создать узел и вставить в конец списка

 // (послеcurrPtr)

 newNode = GetNode(item);

 newNode->link = currPtr->link;

 currPtr->link = newNode;

}

}

Удаление узла в начале списка. Функция DeleteFront реализует удаление узла в начале списка. В этом разделе уже обсуждались алгоритмы для сканирования списка и для вставки новых узлов. Третья списочная операция, удаление узла из списка, знакомит с рядом новых проблем. Часто бывает необходимо удалять первый узел в списке. Операция требует, изменения головы списка для указания на последующий узел за бывшим начальным узлом.

Рисунок 6 – Удаление узла в начале списка

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

// удалить первый узел списка

voidDeleteFront(Node * &head)

{

// сохранить адрес удаляемого узла

Node *p = head;

// убедиться в том, что список не пуст

if (head != NULL)

{

 // передвинуть голову к следующему узлу

 head = head->link;

 // удалитьоригинал

 delete p;

 }

}

Удаление первого элемента, совпадающего с ключом. Общая функция удаления Delete проверяет список и удаляет первый узел, чье значение данных совпадает с ключом. В началеprevPtrустанавливается на NULL, a currPtr — на голову списка. Затем currPtrперемещаетсяпо списку в поисках совпадения с ключом и prevPtrсохраняется так, чтобы он ссылался на предыдущее значение currPtr.

Рисунок 7 – Удаление первого элемента, совпадающего с ключом

Указатели prevPtr и currPtr перемещаются по списку совместно до тех пор, пока currPtr не станет равным NULL или не будет найден ключ (currPtr->data == key).

while (currPtr != NULL &&currPtr->data !=key)

{

// перемещение prevPtr вперед к currPtr

prevPtr = currPtr;

 // перемещение currPtr вперед на один узел

currPtr = currPtr->link;

}

Совпадение возникает, если происходит выход из оператора while с currPtr!=NULL. Тогда можно удалить текущий узел. Существует две возможности. Если prevPtr — это NULL, удаляется первый узел в списке. Иначе, выполняется отсоединение и удаление узла.

if (prevPtr == NULL)

head = head->link;

else

prevPtr->link = currPtr->link;

deletecurrPtr;

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

// удаление первого элемента, совпадающего с ключом

void Delete(Node* & head, int key)

{

Node  *currPtr = head, *prevPtr = NULL;

 // завершить функцию, если список пустой

 if (currPtr == NULL)

 return;

// прохождение до совпадения с ключей или до конца

 while (currPtr != NULL &&currPtr->data != key)

{

 prevPtr = currPtr;

 currPtr = currPtr->link;

 }

// если currPtr не равно NULL, ключ в currPtr

 if (currPtr != NULL)

{

 // prevPtr == NULL означает совпадение в начале списка

 if(prevPtr == NULL)

  head = head->link;

 else

  // совпадение во втором или последующем узле

  // отсоединение этого узла

  prevPtr->link = currPtr->link;

 // удаление узла

 deletecurrPtr;

}

}

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

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

Следующий пример иллюстрирует этот алгоритм. Предположим, что список первоначально содержит целые 60, 65, 74 и 82.

Рисунок 8 – Первоначальный состав списка

Вставка 50 в список: поскольку 60 является первым узлом в списке, большим, чем 50, мы вставляем 50 в голову списка.

Рисунок 9 – Вставка элемента в голову списка

insertFront(head, 50);

Вставка 70 в список: 74 — это первый узел в списке, больший, чем 70. Указатели prevPtr и currPtr обозначают узлы 65 и 74, соответственно.

Рисунок 10 – Вставка элемента в середину списка

newNode = GetNode(70);

newNode->link = prevPtr->link;

prevPtr->link = newNode;

Вставка 90 в список: Сканируется весь список, но узел, больший, чем 90 не найден (currPtr ==NULL). Новое значение больше, или равно всем другим значениям в списке и, следовательно, новое значение должно быть помещено в хвост списка. Когда сканирование завершается, новый узел вставляется после prevPtr.

Рисунок 11 – Вставка элемента в конец списка

newNode = GetNode(90);

newNode->link = prevPtr->link;

prevPtr->link = newNode;

Так как вставка в начале списка приводит к изменению головы, то голову следует передавать по ссылке.

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

// вставить item в упорядоченный список

voidInsertOrder(Node * & head, int item)

{

// currPtrпробегаетпосписку

Node  *currPtr, *prevPtr, *newNode;

// prevPtr == NULL указывает на совпадение в начале списка

prevPtr = NULL; currPtr = head;

// цикл по списку и поиск точки вставки

while (currPtr != NULL)

{

 // точка вставки найдена, если item<текущегоdata

 if (item <currPtr->data)

  break;

 prevPtr = currPtr;

 currPtr = currPtr->link;

 }

// вставка

if (prevPtr == NULL)

// если prevPtr == NULL, вставлять в начало

 InsertFront(head,item);

else

{

// вставить новый узел после предыдущего

 newNode = GetNode(item);

 newNode->link = prevPtr->link;

 prevPtr->link = newNode;

}

}

InsertOrder может использоваться для сортировки элементов, при условии, что оператор сравнения "<" определяется для этого типа данных.

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

// удаление всех узлов в связанном списке

voidClearList(Node * &head)

{

Node *currPtr, *nextPtr;

currPtr = head;

while(currPtr != NULL)

 {

 // записать адрес следующего узла

 nextPtr = currPtr->link;

 // удалить текущий узел

 deletecurrPtr;

 currPtr = nextPtr;

}

// пометить как пустой

 head = NULL;

}

Задание

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

Порядок выполнения работы

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

#include <stdio.h>

#include <alloc.h>

/* Структура для описания односвязного (однонаправленного) списка*/

typedef int ELEMTYPE;

typedefstruct node { ELEMTYPE elem; struct node * next;} *LIST;

/* Инициализация списка/ как пустого */

LIST init(LIST *l)

{ return *l=NULL;}

/* Добавление элемента в голову списка */

LIST cons (ELEMTYPE e,LIST l)

{ LIST news=(LIST)malloc(sizeof(struct node));

news->elem=e;

news->next=l;

returnnews;

}

/* Печать списка целых */

voidprintlist(LIST l)

{ printf("\n") ;

while (l!=NULL) (printf("%5d",l->elem);l=l->next;;}

}

/* Добавление элемента в конец списка */

LIST last(ELEMTYPE e,LIST l)

{ LIST head;

if (!l) { l=(LIST)malloc(sizeof(struct node)) ;

l->elem=e;

l->next=NULL;

return l;

            }

else { head=l;

while (l->nexti=NULL) l=l->next;

l->next= (LIST) malloc (sizeof (struct node) ) ;

      l=l->next;

l->elem=e;

l->next=NULL;

return head;

}

}

/* Удвоить все вхождения данного элемента в список */

LIST doubleE(ELEMTYPE E,LIST l)

{ LIST head=l,tmp;

while (l)

if (l->elem==E)

{/* вставить после него */

tmp=l->next;

l->next=(LIST)malloc(sizeof(struct node)) ;

l->next->elem=l->elem;

l->next->next=tmp;

      l=tmp;

    }

else l=l->next;

return head;

}

/* Удалить из списка все вхождения заданного элемента */

LIST delE(ELEMTYPE E,LIST l)

{ LIST head=l,w;

if (!l) return head;

while (l->next)

if (l->next->elem==E) {w=l->next;l->next=l->next->next; free(w);}

else l=l->next;

return head;

}

/* Тестирующая программа */

voidmain(void)

{

   LIST p;

init(&p) ;

   p=last(0,p); p=cons(l,p); p==cons (2, p) ; p=cons(3,p); p=last(4,p);

   p=last(5,p); p=last(6,p); p=cons(2,p); p=last(4,p);

printlist(p);

   p=doubleE(2,p) ;

printlist(p) ;

   p=doubieE(4,p) ;

printlist(p) ;

   p=delE(4/p) ;

printlist (p) ;

}

Контрольные вопросы

  1.  Что представляют собой связанные списки и какие виды связанных списков вы знаете?
  2.  К каким структурам данным относятся связанные списки?
  3.  С помощью какой структуры данных можно наиболее эффективно решить задачу сортировки и почему?
  4.  Что представляет собой элемент динамической структуры данных?
  5.  Какие операции можно выполнять над списками?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу на языке программирования C++.
  4.  Скриншоты с результатами выполнения программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа № 23.

Стеки

Цель

Формирование навыков организации данных в виде стеков на языке программирования высокого уровня.

Задание для самостоятельной подготовки

  1.  Изучить основы организации данных в видестеков на языке программирования С++[1], стр. 337-343, [2], стр.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Стек (stack) — это список элементов, доступных только в одном конце списка. Элементы добавляются или удаляются из списка только в вершине (top) стека. Подносы в столовой или стопка коробок являются моделями стека.

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

Рисунок 1 – Модель стека

Если гость не любит зеленый перец или лук, это доставит повару больше проблем.Абстрактное понятие стека допускает неопределенно большой список. Логически подносы в столовой могут складываться бесконечно. В действительности подносы находятся на полке, а овощи нанизаны на коротких шампурах. Когда полка или шампур переполнены, мы не можем добавить (Push) еще один элемент в стек. Стек достигает максимального количества элементов, которыми он может управлять. Эта ситуация поясняет значение условия полного стека (stackfull). Другая крайность — вы не можете взять поднос с пустой полки. Условие пустого стека (stackempty) подразумевает, что вы не можете удалить (Pop) элемент. Описание абстрактного типа данных Stack включает только условие пустого стека. Условие полного стека является уместным в том случае, если реализация содержит верхнюю границу размера списка.В алгоритме быстрой сортировки стек используется для хранения границ неупорядоченных фрагментов. В принципе, порядок, в котором они будут обрабатываться, не критичен (главное, чтобы в конце концов все фрагменты оказались отсортированными), но удобнее всего стек использовать из-за простоты его реализации.

В структуре стека важнейшее место занимают операции, добавляющие и удаляющие элементы. Операция Pushдобавляет элемент в вершину стека. Об операции удаления элемента из стека говорят как об извлечении (операция Рор) из стека. На рис. 3 показана последовательность операций Push и Pop. Последний вставленный в стек элемент является первым удаляемым элементом. По этой причине о стеке говорят, что он имеет порядок LIFO (last-in/first-out) (последний пришел/первый ушел).

Рисунок 2 – Помещение в стек и извлечение из него

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

struct Node // Элементстека

{

int left, right;

Node* p;

};

Node* top = 0;// Вершинастека

В C++ определена стандартная константа NULL, значение которой равно нулю типа «указатель», но поскольку правила преобразования типов обеспечивают правильное преобразование целого нуля в нуль типа «указатель», в этой константе нет необходимости.Удобно оформить занесение и выборку элемента в виде отдельных функций.Функция помещения в стек обычно называется push, а выборки — pop. Все необходимое передается функциям через параметры.

// Начальное формирование стека

Node *first(intd)

{

Node *pv = newNode;

pv->d = d;

pv->p = 0;

returnpv;

}

Однако можно и не использовать отдельную функцию для занесения первого элемента в стек, так как если указателю top присвоить 0 перед первым обращением к функции push(), то функция push вполне прилично справится с созданием первого элемента стека:

// Занесениевстек

Node* push(Node* top, const int l, const int r)

{

Node* pv = new Node;                                // 1

pv->left = 1;                                                 // 2

pv->right = г;                                                     // 3

pv->p = top:                                                      // 4

return pv;                                                          // 5

}

// Выборкаизстека

Node* pop(Node* top, int& l, int& r)

{

Node* pv = top->p;                                     // 6

l = top->left;                                                 // 7

r = top->right;                                              // 8

delete top;                                                   // 9

returnpv;                                                    // 10

}

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

// Извлечение  из стека

boolPop(Stek **u, Data&x)

{

if(*u == NULL)

{

     cout << "Pustoj stek" << endl;

     return false;

}

Stek *t = *u;

x.a = t->d.a; // Получаем значения полей на вершине стека

  *u = t->next; // Перенастройка вершины

deletet;     // Удаление ненужного элемента

returntrue;

}

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

Прежде всего мы описываем вспомогательную переменную-указатель и заносим в нее адрес нового элемента стека, который создается с помощью операции new (oпeратор 1). Выделяется столько памяти, сколько необходимо для хранения структуры типа Node. В операторах 2 и 3 информационные поля этой структуры left и right заполняются значениями переданных в функцию границ фрагмента массива. Доступ к этим полям выполняется через указатель pv и операцию выбора ->. Новый элемент становится вершиной стека. Поле его указателя должно ссылаться на элемент, помещенный в стек ранее. Эта ссылка создается в операторе 4. Если «заталкиваемый» в стек элемент является первым, то в качестве первого аргумента функции push() надо задать 0.

Функция push возвращает указатель на вершину стека. Им всегда является указатель на только что занесенный элемент (оператор 5).

Выборка из стека (функция pop) выполняется аналогично. Сначала из вершины стека выбирается указатель на его следующий элемент (оператор 6), который станет новой вершиной стека. Этот указатель является возвращаемым значением функции (оператор 10). Информационная часть элемента заносится в переменные 1 и r, которые передаются в вызывающую функцию по ссылке (операторы 7 и 8). После того как вся информация из элемента выбрана, его можно удалить (оператор 9).

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

Задание

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

Порядок выполнения работы

  1.  Ознакомиться с теорией.
  2.  Выполнить задание (написать программу).
  3.  Ответить на контрольные вопросы.
  4.  Сделать вывод.
  5.  Оформить отчёт о выполненной работе.

Контрольные вопросы

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

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу на языке программирования C++.
  4.  Скриншоты с результатами выполнения программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа № 24.

Очереди

Цель

Формирование навыков организации данных в виде очереди на языке программирования высокого уровня.

Задание для самостоятельной подготовки

  1.  Изучить основы организации данных в виде очереди на языке программирования С++[1], стр. 351-354, [2], стр.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Очередь — это линейный список информации, работа с которой происходит по принципу "первым пришел — первым вышел" (first-in, first-out); этот принцип (и очередь как структура данных) иногда еще называется FIFO. Это значит, что первый помещенный в очередь элемент будет получен из нее первым, второй помещенный элемент будет извлечен вторым и т.д. Это единственный способ работы с очередью; произвольный доступ к отдельным элементам не разрешается.

Можно реализовать очередь в памяти компьютера в блоке смежных ячеек, схожим со стеком образом. Так как необходимо производить операции на обоих концах структуры, то, в отличие от стека, где требуется одна дополнительная ячейка, здесь отдельно заводятся еще две ячейки памяти для использования в качестве указателей. Один из них, называемый указателем головы, предназначен для отслеживания головы очереди; другой, указатель хвоста, предназначен для отслеживания хвоста очереди. Если очередь пуста, оба указателя указывают на одно и то же место в памяти (рис. 1).

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

Рисунок 1 -  Очередь с указателями головы и хвоста:  a – пустая очередь; б –   после добавления записи А;  в – после добавления записи В;  г – после удаления записи А

Но с этой системой хранения связана серьезная проблема. Если не управлять очередью, она постепенно будет перемещаться по памяти, как ледник, разрушая остальные данные на своем пути (рис. 2).

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

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

Рисунок  2 – Очередь, «ползающая» по памяти: а – очередь с записями А, В и С; б – очереди после добавления D, E и F и удаления A и B; в – вид очереди после добавления G и H и удаления C и D

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

Этот способ реализации называется циклической очередью (circularqueue), так как образуется цикл из ячеек памяти, выделенных для очереди (рис. 3). С точки зрения этой очереди последняя ячейка в блоке соседствует с первой.

Рисунок 3 – Фактическое устройство циклической очереди, содержащей буквы от F до O (а) и ее абстрактное представление, где последняя ячейка блока «граничит» с первой (б)

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

Создание очереди описано на псевдокоде

  1.       r = new (node);//создание нового узла очереди

   (*r).elem = Элем; // указатель на первый                                                  

     //элемент очереди

       (*r).sled = NULL; //указатель на следующий

     //пустой узел

Рисунок 4 - Первый элемент в очереди

  1.  no = r; // указатель на начало очереди

ko = r; // указатель на конец очереди


Рисунок 5 - Настройка указателей начала и конца очереди

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

  1.  Продолжим заполнение очереди:

r = new (node); // создание еще одного узла

  (*r).elem = Элем1; // указатель на первый элемент

  (*r).sled = NULL; // указатель на

   //следующий(пустой) узел

Рисунок 6 - Создание нового элемента очереди

  1.  Настроим указатель на конец очереди:

(*ko).sled = r; // указатель на второй узел

ko = r; // указатель на конец очереди

Рисунок 7 – Настройка указателя на конец очереди

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

Представим описанный алгоритм в виде функции на языке C++:

void POSTROENIE (node *no, node *ko)

// Построение очереди на базе однонаправленного

// линейного списка без заглавного звена:

// *no - указатель на начало очереди,

// *ko - указатель на конец очереди.

{   //открытие тела функции POSTROENIE

node *r;  // указатель начала очереди

intel; // целочисленная переменная вводимых элементов

        // очереди

cin>>el; // ввод элемента

if (el!=0) // в случае если введено ‘0’

{ // начало if

r = new (node); // создание узла

   (*r).elem = el; // указатель на последний введенный

                  // элемент

   (*r).sled = NULL; // указатель на пустой узел

   *no = r; //указатель начала очереди равен

            //последнему созданному узлу

   *ko = r; //указатель хвоста очереди равен последнему

            //созданному узлу

cin>>el; // ввод следующего элемента

while (el!=0) // пока он не равен нулю делаем

{ // открытие wile

r = new (node); // создание узла

(*r).elem = el; // указатель на последний введенный

              // элемент

(*r).sled = NULL; // указатель на пустой узел

(*ko).sled = r; ;// присвоение указателя очереди началу

                // нового звена

*ko = r; // конец очереди это созданное звено

cin>>el; // ввод следующего элемента

}// закрытие wile

} // завершение if

else // условный оператор иначе

 { r = NULL; *no = r; *ko = r;} // производим

                               //обнуление указателей

} //закрытие тела функции POSTROENIE

Тут же приведем функцию для просмотра содержимого очереди:

void VYVOD (node *no, node *ko)

// Вывод содержимого очереди.

// *no - указатель на начало очереди,

// *ko - указатель на конец очереди.

{  //открытие тела функции VYVOD

node *r; // указатель начала очереди

cout<< "Очередь: "; // Вывод строки на дисплей

r = *no;  // узел очереди это ее начало

while (r!=NULL) // делаем пока не дойдем до конца

                //очереди

{ // открытие wile

cout<<(*r).elem<<" "; // вывод элементов очереди

r = (*r).sled; //присвоение узлу очереди следующего

                 //элемента

}  // закрытие wile

cout<<endl;  //возврат каретки

}//закрытие тела функции VYVOD

Замечание. Очереди целесообразно хранить в памяти ЭВМ в виде кольцевого списка с двумя указателями (один - на начало, другой - на конец очереди):

Рисунок 8 - Представление очереди

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

1.5 Алгоритм добавления звена к очереди.

Звено добавляется в конец очереди.

Рисунок 9 - Исходная очередь

  1.  Построение добавляемого звена:

   r = new (node); // создание узла очереди

   (*r).elem = Элем; // указатель на первый элемент

   (*r).sled = NULL; // указатель на

   //следующий (пустой) узел

Рисунок 10 - Заполнение добавляемого звена

2. Присоединяем звено к очереди:

   (*ko).sled = r; // присвоение указателя конца

       //новому звену очереди

Рисунок 11 - Результат присоединения звена

  1.  "Настраиваем" указатель ko на конец очереди:

ko = r; // конец очереди есть добавляемое звено

Изобразим результат добавления звена:

Рисунок 12 –«Настройка» указателя

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

Оформим алгоритм в виде функции на языке C++:

void DOBAVLENIE (node *no, node *ko, int el)

// Добавление звена  с информационным  полем  el

//* к очереди, определенной указателями *no и *ko.

{ // открытие тела функции DOBAVLENIE

node *r; // указатель начала очереди

r = new (node);  // создание узла

 (*r).elem = el; // указатель на введенный  элемент            

 (*r).sled = NULL;  // указатель на пустой узел

if (*no!=NULL)//если очередь не пуста

{ // открытие if

(*ko).sled = r; // присвоение указателя очереди началу

              //нового звена

*ko = r; // указатель хвоста очереди это созданное

        //звено

} // закрытие if

Else // иначе

{ // открытие else

     *no = r; //указатель головы на новом звене

     *ko = r; // указатель хвоста на новом звене

} //закрытие else

} // закрытие тела функции DOBAVLENIE

Алгоритм удаления звена из очереди.

Пусть очередь не пуста (no!=NULL). Изобразим ее схематически:

Рисунок 13 - Очередь

Приступим к удалению звена. Напомним, что звено удаляется из очереди из ее начала.

  1.  Сохраним удаляемый элемент:

klad = (*no).elem; //первый элемент очереди

   //  сохранен в переменной klad

Рисунок 14 - Сохранение удаляемого элемента

  1.  Сохраним указатель на удаляемый элемент и "перенастроим" указатель на начало очереди:

q = no; // сохранение указателя на удаляемый элемент

no = (*no).sled; // присваивание указателя начала

                    // очереди следующему элементу

Рисунок 15 –«Перенастройка» указателя на начало очереди

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

 delete q; //удаление звена очереди

Рисунок 16 - Возврат памяти

Запишем приведенную схему в виде функции на языке C++:

void YDALENIE (node *no, node *ko, int klad)

// Удаление звена из очереди, определенной указателями //*no  и *ko. Значение информационного  поля  //удаленного звена

// сохраняется в параметре klad.

{// открытие тела функции YDALENIE

node *q; // указатель на удаляемое звено

if (*no==NULL)// если очередь пуста

cout<< "Удалить нельзя, так как очередь пуста!\n";

// вывод текста на дисплей

else // иначе

{ // открытие else

*klad = (*no).elem;//сохранение первого элемента в klad

q = *no; // сохранение указателя на удаляемый элемент   

         //в q

*no = (*no).sled; // присваивание указателя начала

                 // очереди следующему элементу

deleteq; // удаление первого звена

} // закрытие else

}// закрытие тела функции YDALENIE

Задание

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

Порядок выполнения работы

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

При выполнении индивидуального задания придерживаться следующей последовательности действий:

  •  изучить словесную постановку задачи;
  •  разработать программу, решающую поставленную задачу;
  •  протестировать и отладить программу;
  •  написать и представить к защите отчет по работе.

Контрольные вопросы

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

Вставка записи А

Вставка записи В

Вставка записи С

Удаление записи

Удаление записи

Вставка записи D

Вставка записи E

Удаление записи

Вставка записи F

Удаление записи

  1.  Если очередь реализована в циклической форме, то как соотносятся указатели головы и хвоста в случае пустой очереди? Если очередь заполнена? Как можно понять, пуста очередь или заполнена?
  2.  Предположим, что для хранения каждой записи в очереди требуется одна ячейка памяти, значение указателя головы очереди равно 11, а хвоста — 17. Каковы значения этих указателей после добавления одной записи и удаления двух? 26. Выполните задания.

а) Очередь, реализованная в циклической форме, находится в состоянии, показанном на схеме ниже. Нарисуйте схему, показывающую структуру очереди после добавления букв G и R, удаления трех букв и добавления букв D и Р.

б) Какая ошибка произойдет в очереди из задания (а), если буквы G, R, Dи Р добавить, не удаляя другие буквы?

Требования к отчету

Отчет должен содержать:

1. Тему и цель работы.

2. Задание.

3. Программу на языке программирования C++.

4. Скриншоты с результатами выполнения программы.

5. Ответы на контрольные вопросы.

6. Выводы о проделанной работе.

Лабораторная работа № 25.

Деревья

Цель

Формирование навыков организации данных в виде деревьев на языке программирования высокого уровня.

Задание для самостоятельной подготовки

  1.  Изучить основы организации данных в видедеревьев на языке программирования С++[1], стр. 337-343, [2], стр.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Рассмотрим еще один способ хранения множества значений – представление множеств с помощью деревьев.

Рисунок 1 – Терминология дерева

При обсуждении деревьев применяется специальная терминология. Программисты не являются специалистами в области филологии, и поэтому терминология, применяемая в теории графов (а ведь деревья представляют собой частный случай графов!), является классическим примером неправильного употребления слов. Первый элемент дерева называется корнем (root). Каждый элемент данных называется вершиной дерева (node), а любой фрагмент дерева называется поддеревом (subtree). Вершина, к которой не присоединены поддеревья, называется заключительным узлом (terminal node) или листом (leaf). Высота (height) дерева равняется максимальному количеству уровней от корня до листа. При работе с деревьями можно допустить, что в памяти они существуют в том же виде, что и на бумаге. Но помните, что дерево — всего лишь способ логической организации данных в памяти, а память линейна.

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

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

На первом уровне двоичного дерева может быть только одна вершина – корень, на втором – две (сыновья корня), на третьем – четыре (сыновья сыновей корня). В общем случае на i-м уровне может быть до 2i-1 вершин. Дерево, содержащее n полностью заполненных уровней, будем называть полным. Полное двоичное дерево содержит=2i-1 вершин.

Всякое непустое двоичное T-дерево разбивается на 3 части: корень, левое и правое поддеревья. Отсюда можно дать следующее рекурсивное определение двоичного дерева:

пустое дерево – двоичное дерево;

вершина с левым и правым двоичными поддеревьями – двоичное дерево.

Левое и правое поддеревья могут быть пустыми.

Высотой поддерева будем считать максимальную длину цепи y[1]..y[n] его вершин такую, что y[i+1] – сын y[i] для всех i. Высота пустого дерева равна 0. Высота дерева из одного корня – единице.

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

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

Важное свойство упорядоченного дерева: все элементы его различны.

В дальнейшем будет идти речь только о двоичных упорядоченных деревьях, опуская слова «двоичный» и «упорядоченный».

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

Приведенная ниже функция stree() создает упорядоченное двоичное дерево:

struct tree {

 char info;

 struct tree *left;

 struct tree *right;

};

struct tree *stree(

 struct tree *root,

 struct tree *r,

 char info)

{

 if(!r) {

   r = (struct tree *) malloc(sizeof(struct tree));

   if(!r) {

     printf("Не хватает памяти\n");

     exit(0);

   }

   r->left = NULL;

   r->right = NULL;

   r->info = info;

   if(!root) return r; /* первый вход */

   if(info < root->info) root->left = r;

   else root->right = r;

   return r;

 }

 if(info < r->info)

   stree(r,r->left,info);

 else

   stree(r,r->right,info);

 return root;

}

Приведенный выше алгоритм просто следует по ссылкам дерева, переходя к левой или правой ветви очередной вершины на основании содержимого поля info до достижения места вставки нового элемента. Чтобы использовать эту функцию, необходимо иметь глобальную переменную-указатель на корень дерева. Этот указатель изначально должен иметь значение нуль (NULL). При первом вызове функция stree() возвращает указатель на корень дерева, который нужно присвоить глобальной переменной. При последующих вызовах функция продолжает возвращать указатель на корень. Допустим, что глобальная переменная, содержащая корень дерева, называется rt. Тогда функция stree() вызывается следующим образом:

/* вызов функции street() */

rt = street(rt, rt, info);

Функция stree() использует рекурсивный алгоритм, как и большинство процедур работы с деревьями.

#include<iostream>

usingnamespace std;

struct Node

{

int d;

 Node *left;

 Node *right;

};

Node * first (int d);

Node * search_insert(Node *root, int d);

void print_tree(Node *root, int level);

//

int main()

{

int b[] = {10, 25, 20, 6, 21, 8, 1, 30};

 Node *root = first(b[0]);

for (int i = 1; i<8; i++)search_insert(root, b[i]);

print_tree(root, 0);

return 0;

}

// Формирование первого элемента дерева

Node * f1rst(int d)

{

 Node *pv = new Node;

 pv->d = d;

 pv->left = 0;

pv->right = 0;

return pv;

}

// Поиск с включением

Node * search_insert(Node *root, int d)

{

 Node *pv = root, *prev;

bool found = false;

while (pv && !found)

 {

  prev = pv;

if(d == pv->d) found = true;

elseif(d < pv->d) pv = pv->left;

else               pv = pv->right;

 }

if (found) return pv;

// Создание нового узла

 Node *pnew = new Node;

pnew->d = d;

 pnew->left = 0;

 pnew->right = 0;

if (d < prev->d)

// Присоединение к левому поддереву предка

    prev->left = pnew;

else

// Присоединение к правому поддереву предка

prev->right = pnew;

return pnew;

}

// Обходдерева

void print_tree(Node *p, int level)

{

if (p)

  {

    print_tree(p->left, level+1);  // выводлевогоподдерева

for (int i = 0; i<level; i++)cout <<"  ";

cout << p->d << endl;        // вывод корня поддерева

    print_tree(p->right, level+1); // вывод правого поддерева

  }

}

Текущий указатель для поиска по дереву обозначен pv, указатель на предка pv обозначен prev, переменная pnew используется для выделения памяти под включаемый в дерево узел. Рекурсии удалось избежать, сохранив всего одну переменную (prev) и повторив при включении операторы, определяющие, к какому поддереву присоединяется новый узел.

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

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

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

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

Итак, в худшем случае хранение в упорядоченном дереве никакого выигрыша по сравнению с обычным способом хранения множества в массиве не дает. В лучшем случае для всех операций (поиск/добавление/удаление) получается логарифмическая сложность, а это очень хорошо (ни один из рассмотренных ранее способов хранения такого результата для всех операций не давал). Но как гарантировать логарифмическую сложность всегда? Выход открывает способ, который был предложен в 1962 году двумя советскими математиками – Г.М.Адельсоном-Вельским и Е.М.Ландисом.

Так исторически сложилось, что у АВЛ-деревьев  есть два альтернативных названия: АВЛ-деревья и сбалансированные деревья. АВЛ произошло от фамилий изобретателей.

Идеально сбалансированным называется дерево, у которого для каждой вершины выполняется требование: число вершин в левом и правом поддеревьях различается не более, чем на 1. Однако идеальную сбалансированность довольно трудно поддерживать. В некоторых случаях при добавлении/удалении может потребоваться значительная перестройка дерева, не гарантирующая логарифмической сложности. Поэтому Г.М.Адельсон-Вельский и Е.М.Ландис ввели менее строгое определение сбалансированности и доказали, что при таком определении можно написать программы добавления/удаления, имеющие логарифмическую сложность и сохраняющие дерево сбалансированным.

Дерево считается сбалансированным по АВЛ (в дальнейшем просто «сбалансированным»), если для каждой вершины выполняется требование: высота левого и правого поддеревьев различаются не более, чем на 1. Не всякое сбалансированное дерево идеально сбалансировано, но всякое идеально сбалансированное дерево сбалансировано.

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

В сбалансированном дереве показатели сбалансированности всех вершин лежат в пределах от -1 до 1. При операциях добавления/удаления могут появляться вершины с показателями сбалансированности -2 и 2.

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

Рисунок 2 – Малое левое вращение

На приведенном рисунке прямоугольниками обозначены поддеревья. Рядом с поддеревьями указана их высота. Поддеревья помечены арабскими цифрами. Кружочками обозначены вершины. Цифра рядом с вершиной - показатель сбалансированности в данной вершине. Буква внутри кружка - условное обозначение вершины.

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

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

Рисунок 3 – малое правое вращение

Несколько сложнее случай, когда показатель сбалансированности в вершине, в которой произошло нарушение баланса равен -2, а показатель сбалансированности в корне левого поддерева равен 1 или 0. В этом случае применяется преобразование, называемое большим левым вращением. Как видно из рисунка здесь во вращении участвуют три вершины, а не две как в случае малых вращений.

Рисунок 4 – Большое правое вращение

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

Схематично алгоритм вставки нового элемента в сбалансированное дерево будет состоять из следующих трех основных шагов:

Поиск по дереву.

Вставка элемента в место, где закончился поиск, если элемент отсутствует.

Восстановление сбалансированности.

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

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

Алгоритм удаления элемента из сбалансированного дерева будет выглядеть так:

- поиск по дереву.

- удаление элемента из дерева.

- восстановление сбалансированности дерева (обратный проход).

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

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

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

Понятно, что в случае полного двоичного дерева (наилучший случай) мы получим сложность T(log(n)) (на каждом шаге размер дерева поиска будет сокращаться вдвое). Рассмотрим минимальное сбалансированное дерево (худший случай). Таким будет дерево, у которого для каждой вершины высота левого и правого поддеревьев различаются на 1. Для такого дерева можно записать следующую рекуррентную формулу для числа вершин (h – высота дерева):

Покажем, что h<log2(Nh). Для этого необходимо и достаточно показать, что 2h>Nh. Докажем последнее методом математической индукции.

а) h=0: 20>N0=0;

б) h=1: 21>N1=1;

в) h>1: Пусть 2h-2>Nh-2 и 2h-1>Nh-1.

Тогда 2h-2+2h-1>Nh-2+ Nh-1.

И далее получаем 2h>1+2h-2+2h-1>1+Nh-2+ Nh-1=Nh, что и требовалось доказать.

Таким образом, мы доказали, что алгоритмы поиска/добавления/удаления элементов в сбалансированном дереве имеют сложность T(log(n)).

Г.М. Адельсон-Вельский и Е.М. Ландис доказали теорему, согласно которой высота сбалансированного дерева никогда не превысит высоту идеально сбалансированного дерева более, чем на 45%.

Задание

(номер варианта задания соответствует вашему номеру в журнале)

1. Написать рекурсивную числовую функцию, подсчитывающую сумму элементов дерева.

2. Написать функцию, которая находит наибольший элемент дерева.

3. Написать функцию, которая находит наименьший элемент дерева.

4. Напишите процедуру, которая удаляет из дерева все четные элементы.

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

6. Написать рекурсивную процедуру, которая печатает элементы из всех листьев дерева.

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

1 группа

1 курс

2 группа

ФМИ

3 группа

2 курс

4 группа

8. Написать рекурсивную функцию, которая определяет глубину заданного элемента на дереве и возвращает –1, если такого элемента нет.

9. Написать процедуру, которая печатает (по одному разу) все вершины дерева.

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

11. Написать процедуру, которая считает глубину дерева.

12. Отсортировать массив А путем включения его элементов в дерево и скопировать отсортированные данные обратно в А.

13. Задана последовательность слов. Определить частоту вхождения каждого из слов в последовательность.

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

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

15. Организовать хранение сбалансированного дерева в памяти ЭВМ, а также реализовать основные операции над сбалансированным деревом: поиск/добавление/удаление.

16. Напишите программу, содержащую процедуру или функцию, которая подсчитывает число вершин на каждом уровне непустого дерева (корень считать вершиной 0-го уровня). В программе используйте подпрограммы.

17. Напишите программу, содержащую процедуру или функцию, которая определяет максимальную глубину непустого дерева Т, т.е. число ветвей в самом длинном из путей от корня дерева до листьев.

18. Постройте два дерева. Проверьте, является ли одно из них поддеревом другого. Если "нет", то включите это поддерево. В программе используйте подпрограммы.

19.Написать программу формирования дерева. Удалите из дерева все повторяющиеся элементы. В программе используйте подпрограммы.

20. Объедините два дерева в одно идеально сбалансированное. В программе используйте подпрограммы.

Порядок выполнения работы

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

При выполнении индивидуального задания придерживаться следующей последовательности действий:

- изучить словесную постановку задачи;

- разработать программу, решающую поставленную задачу;

- оттестировать и отладить программу;

- написать и представить к защите отчет по работе.

Контрольные вопросы

  1.  Что такое дерево, двоичное дерево, поддерево?
  2.  Приведите два способа хранения деревьев в памяти ЭВМ, укажите их недостатки и достоинства.
  3.  Нарисуйте бинарное дерево, в котором вы хранили бы список R S T U V W X Y и Z для последующего поиска.
  4.  Нарисуйте схему, показывающую, как дерево, приведенное ниже, хранится в памяти с использованием указателей на левых и правых потомков. Затем нарисуйте схему последовательного хранения элементов дерева с использованием альтернативной системы хранения.

                                             Y

                                   X                       Z

                               W

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу на языке программирования C++.
  4.  Скриншоты с результатами выполнения программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа №26.

Ввод-вывод в файл

Цель

Формирование навыков организации ввода-вывода данных в файл на языке программирования высокого уровня.

Задание для самостоятельной подготовки

  1.  Изучить основные понятия файловой организации данных, а также функции языкаС++ для работы с файлами [1], стр. 337-343, [2], стр.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Использование файлов в программе предполагает следующие операции:

  •  создание потока;
  •  открытие потока и связывание его с файлом;
  •  обмен (ввод-вывод);
  •  закрытие файла.

Для чтения и записи данных, тип которых может занимать более 1 байта, в файловой системе языка С имеется две функции: fread() и fwrite(). Эти функции позволяют читать и записывать блоки данных любого типа. Их прототипы следующие:

size_t fread(void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);

size_t fwrite(const void *буфер, size_t колич_байт, size_t счетчик, FILE *уф);

Для fread() буфер — это указатель на область памяти, в которую будут прочитаны данные из файла. А для fwrite() буфер — это указатель на данные, которые будут записаны в файл. Значение счетчик определяет, сколько считывается или записывается элементов данных, причем длина каждого элемента в байтах равна колич_байт. (Вспомните, что тип size_t определяется как одна из разновидностей целого типа без знака.) И, наконец, уф — это указатель файла, то есть на уже открытый поток.

Функция fread() возвращает количество прочитанных элементов. Если достигнут конец файла или произошла ошибка, то возвращаемое значение может быть меньше, чем счетчик. А функция fwrite() возвращает количество записанных элементов. Если ошибка не произошла, то возвращаемый результат будет равен значению счетчик.

Использование fread() и fwrite()

Как только файл открыт для работы с двоичными данными, fread() и fwrite() соответственно могут читать и записывать информацию любого типа. Например, следующая программа записывает в дисковый файл данные типов double, int и long, a затем читает эти данные из того же файла. Обратите внимание, как в этой программе при определении длины каждого типа данных используется функция sizeof().

/* Запись несимвольных данных в дисковый файл

  и последующее их чтение.  */

#include <stdio.h>

#include <stdlib.h>

int main(void)

{

 FILE *fp;

 double d = 12.23;

 int i = 101;

 long l = 123023L;

 if((fp=fopen("test", "wb+"))==NULL) {

   printf("Ошибка при открытии файла.\n");

   exit(1);

 }

 fwrite(&d, sizeof(double), 1, fp);

 fwrite(&i, sizeof(int), 1, fp);

 fwrite(&l, sizeof(long), 1, fp);

 rewind(fp);

 fread(&d, sizeof(double), 1, fp);

 fread(&i, sizeof(int), 1, fp);

 fread(&l, sizeof(long), 1, fp);

 printf("%f %d %ld", d, i, l);

 fclose(fp);

 return 0;

}

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

Одним из самых полезных применений функций fread() и fwrite() является чтение и запись данных пользовательских типов, особенно структур. Например, если определена структура 

struct struct_type {

 float balance;

 char name[80];

} cust;

то следующий оператор записывает содержимое cust в файл, на который указывает fp:

fwrite(&cust, sizeof(struct struct_type), 1, fp);

Кроме основных функций ввода/вывода, о которых шла речь, в системе ввода/вывода языка С также имеются функции fprintf() и fscanf(). Эти две функции, за исключением того, что предназначены для работы с файлами, ведут себя точно так же, как и printf() и scanf(). Прототипы функций fprintf() и fscanf() следующие:

int fprintf(FILE *уф, const char *управляющая_строка, ...);

int fscanf(FILE *уф, const char *управляющая_строка, ...);

где уф — указатель файла, возвращаемый в результате вызова fopen(). Операции ввода/вывода функции fprintf() и fscanf() выполняют с тем файлом, на который указывает уф.

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

/* пример использования fscanf() и fprintf() */

#include <stdio.h>

#include <io.h>

#include <stdlib.h>

int main(void)

{

 FILE *fp;

 char s[80];

 int t;

 if((fp=fopen("test", "w")) == NULL) {

   printf("Ошибка открытия файла.\n");

   exit(1);

 }

 printf("Введите строку и число: ");

 fscanf(stdin, "%s%d", s, &t); /* читать с клавиатуры */

 fprintf(fp, "%s %d", s, t); /* писать в файл */

 fclose(fp);

 if((fp=fopen("test","r")) == NULL) {

   printf("Ошибка при открытии файла.\n");

   exit(1);

 }

 fscanf(fp, "%s%d", s, &t); /* чтение из файла */

 fprintf(stdout, "%s %d", s, t); /* вывод на экран */

 return 0;

}

Маленькое предупреждение. Хотя читать разносортные данные из файлов на дисках и писать их в файлы, расположенные также на дисках, часто легче всего именно с помошью функций fprintf() и fscanf(), но это не всегда самый эффективный способ выполнения операций чтения и записи. Так как данные в формате ASCII записываются так, как они должны появиться на экране (а не в двоичном виде), то каждый вызов этих функций сопряжен с определенными накладными расходами. Поэтому, если надо заботиться о размере файла или скорости, то, скорее всего, придется использовать fread() и fwrite().

Задание

Вариант 1

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

Вариант 2

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

Вариант 3

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

Вариант 4

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

Вариант 5

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

Вариант 6

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

Вариант 7

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

Вариант 8

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

Вариант 9

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

Вариант 10

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

Вариант 11

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

Вариант 12

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

Вариант 13

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

Вариант 14

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

Вариант 15

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

Вариант 16

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

Вариант 17

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

Вариант 18

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

Вариант 19

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

Вариант 20

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

Порядок выполнения работы

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

Итак, мы имеем текстовый файл неизвестного размера, состоящий из неизвестного количества предложений. Предложение может занимать несколько строк, поэтому читать файл построчно неудобно — это привело бы к неоправданно сложному алгоритму. При решении аналогичной задачи в первой книге практикума было принято решение выделить буфер, в который поместится весь файл. Такое решение тоже нельзя признать идеальным — ведь файл может иметь сколь угодно большие размеры, и тогда программа окажется неработоспособной.

Попробуем читать файл пословно, как и в предыдущей программе, в переменную word типа string, и отправлять каждое прочитанное слово в строковый поток sentence типа ostringstream, который, как вы уже догадались, будет хранилищем очередного предложения.

При таком подходе, однако, есть проблема, связанная с потерей разделителей при чтении файла операцией fin>>word. Чтобы ее решить, будем «заглядывать» в следующую позицию файлового потока fin с помощью метода peek(). При обнаружении символа-разделителя его нужно отправить в поток sentence и переместиться на следующую позицию в потоке fin, используя метод seek(). Подробности обнаружения символа-разделителя инкапсулируем в глобальную функцию isLimit().

Осталось решить подзадачи:

  •  обнаружить конец предложения, то есть один из символов '.', '!', '?';

если это вопросительное предложение, то вывести его в поток cout, в противном случае очистить поток sentence для накопления следующего предложения.

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

#include <fstream>

#include <sstream>

#include <string>

#include "CyrlOS.h"    // for Visual C++ 6.0

using namespace std:

boolisLimit(char c)  {

charlim[] = {'   ',   '\t',   '\r'};

for (int i = 0; i <sizeof(lim); ++i)

if (c == lim[i]) return true; return false;

}

int main() {

ifstream fin("infile.txt", ios: :in|ios: ;nocreate);

if (!fin) { cout « "Ошибка открытия файла." « endl; return 1; }

int count =0; string word; ostringstream sentence; whiledfin.eof()) { char symb;

while(isLimit(symb = fin.peek())) { sentence « symb; if (symb == '\n') break; fin.seekg(1, ios: :cur);

}

fin » word;

sentence « word;

char last = word[word.size() - 1];

if ((last — '.') || (last == '!')) {

sentence.str(""); // очисткапотока

continue;

}

if (last == '?') {

cout « sentence.str(); sentence.str(""); count++; } }

if (!count) cout « "Вопросительных предложений нет."; cout « endl;

return 0;

}

Контрольные вопросы

  1.  Что такое файл?
  2.  В каком включаемом файле объявляются потоки cin и coutl
  3.  Для чего используется функция fail?
  4.  Что такое функция EOF и для чего она используется?
  5.  Каким образом можно упростить ввод имен файлов?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу на языке программирования C++.
  4.  Скриншоты с результатами выполнения программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа № 27.

Индексация данных

Цель

Формирование навыков в организации данных с использованием индексации.

Задание для самостоятельной подготовки

  1.  Изучить основные положения индексации данных [1], стр. 393-397.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

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

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

Рисунок 1- Файл с частичным индексом

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

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

Значение

Индексируемого поля ("Год рождения")

Номера, строк

1958

3

1959

5, 17, 123, 256

1960

31, 32, 77

1961

11, 45, 58, 167, 231

1962

7, 8, 9, 10, 234,235,236

Строки инвертированного списка упорядочиваются по значению индексируемого поля. Для доступа к нужной строке исходной таблицы сначала в упорядоченном инвертированном списке отыскивается строка с требуемым значением поля,* затем считывается номер соответствующей строки (строк) в исходной таблице и далее по нему уже осуществляется непосредственный доступ к искомой строке базовой таблицы.

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

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

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

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

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

Каждая внутренняя вершина, если она полностью заполнена, содержит информацию о n–1 различных последовательно возрастающих значениях индексируемого поля по следующей схеме

Рисунок  2- Структура внутренней вершины Б-дерева

где: Хi –i-е значение индексируемого поля, при этом ХiJXi+1 – указатель на вершину, содержащую значения индексируемого поля, меньшие или равные Xi.Число n называется порядком Б-дерева. Листовая вершина, в отличие от внутренней, содержит информацию о нахождении страницы в файле базы данных с записями-кортежами, имеющими соответствующие значения индексируемого поля.

Рисунок3 -Структура листовой вершины Б-дерева

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

СбалансированностьБ-дерева означает одинаковое количество потомков до листовой вершины по любым разветвлениям от корневой вершины. В качестве примера на рис. 2.19 приведено Б-дерево 3-го порядка уровня 2, построенное для поля «Год рождения» таблицы «Сотрудники».

Рисунок 4- Пример Б-дерева 3-го порядки уровня 2

Как правило, порядок Б-дерева выбирается таким, чтобы информация одной полностью заполненной вершины соответствовала странице файла данных. В силу того что объем одной страницы файлов данных существенно больше размера полей, то в большинстве случаев в одну полностью заполненную страницу вместе с указателями помещается большое количество значений индексируемого поля, исчисляемое сотнями и даже тысячами значений (n >> 100...1000). Это обстоятельство обусловливает сравнительно небольшой уровень Б-деревьев на практике (порядка 2...4) даже в тех случаях, когда количество строк в базовой таблице исчисляется десятками тысяч. В результате доступ к нужной записи по определенному значению индексируемого поля через Б-дерево осуществляется за небольшое количество страничных обменов между внутренней ивнешней памятью по следующему алгоритму: в оперативную память из внешней считывается страница с корневой вершиной и последовательно просматривается до первого значения, превышающего значение индексируемого поля нужной записи. При этом определяется ссылка (номер) страницы-потомка (внутренней или листовой); в оперативную память считывается страница-потомок. Если она внутренняя, то ее обработка производится аналогично корневой. Если страница-потомок является листовой, то она последовательно просматривается до нахождения нужного значения индексируемого поля. При этом определяется номер страницы файла данных, которая содержит нужную запись; если при просмотре листовой страницы нужное значение индексируемого поля не находится, то поиск считается отрицательным, т. е. принимается решение о том, что строки-кортежа с требуемым значением индексируемого поля в таблице-отношении (файле данных) нет.

Анализ данного алгоритма показывает, что при поиске нужного значения индексируемого поля по индексу в виде Б-дерева требуется такое количество страничных обменов между внешней и внутренней памятью, которое равно уровню Б-дерева плюс единица. При достаточно большом значении n, а это, как уже отмечалось, наиболее распространенная ситуация, уровень m Б-дерева невелик (m >> 2..3), и, следовательно, количество страничных индексных обменов с памятью также невелико. При этом сбалансированность Б-дерева обусловливает одинаковые затраты по доступу к любой записи с любым значением индексируемого поля. Сбалансированность Б-деревьев обеспечивается легко алгоритмизируемым правилом их построения (роста) при включении нового значения индексируемого поля.

Включение нового значения индексируемого поля осуществляется следующим образом.

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

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

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

Если при занесении среднего значения переполненной листовой страницы в страницу-предок происходит переполнение самой страницы-предка, то она аналогично делится пополам, «посылая» свое среднее значение своему предку. Если при этом происходит переполнение корневой страницы, то она также делится на две новые внутренние страницы, а ее среднее значение образует новую корневую страницу, повышая уровень дерева на единицу и т. д. (говорят, что Б-дерево «растет» вверх).

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

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

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

Если после удаления размер занятого пространства памяти текущей листовой страницы в сумме с размером занятого пространства левого (правого) брата больше, чем размер памяти одной страницы, то процесс заканчивается.

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

Описанный алгоритм удаления значений индексируемого поля соответствует одной из наиболее широко применяемых разновидностей Б-деревьев—Б*-деревьев, которые позволяют использовать в среднем до 2/3 пространства всех страниц (вершин) дерева.

Структура Б-деревьев является эффективным способом индексации больших массивов данных и широко применяется в современных СУБД.

Рассмотрим, например, следующий массив:

char p[10];

Следующие два выражения идентичны:

p

&p[0]

Выражение

p == &p[0]

принимает значение ИСТИНА, потому что адрес 1-го элемента массива — это то же самое, что и адрес массива.

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

int *p, i[10];

p = i;

p[5] = 100;  /* в присваении используется индекс */

*(p+5) = 100; /* в присвоении используется адресная арифметика */

Оба оператора присваивания заносят число 100 в 6-й элемент массива i. Первый из них индексирует указатель p, во втором применяются правила адресной арифметики. В обоих случаях получается один и тот же результат.

Можно также индексировать указатели на многомерные массивы. Например, если а — это указатель на двухмерный массив целых размерностью 10×10, то следующие два выражения эквивалентны:

a

&a[0][0]

Более того, к элементу (0,4) можно обратиться двумя способами: либо указав индексы массива: а[0][4], либо с помощью указателя: *((int*)а+4). Аналогично для элемента (1,2): а[1][2] или *((int*)а+12). В общем виде для двухмерного массива справедлива следующая формула:

a[j][k] эквивалентно *((базовый_тип*)а+(j*длина_строки)+k)

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

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

int num[10][10];

/* ... */

void  pr_row(int j)

{

 int *p, t;

 p = (int *) &num[j][0]; /* вычисление адреса 1-го

                            элемента строки номер j */

 for(t=0; t<10; ++t) printf("%d ", *(p+t));

}

Эту функцию можно обобщить, включив в список аргументов номер строки, длину строки и указатель на 1-й элемент:

void pr_row(int j, int row_dimension, int *p)

{

 int t;

 p = p + (j * row_dimension);

 for(t=0; t<row_dimension; ++t)

   printf("%d ", *(p+t));

}

/* ... */

void f(void)

{

 int num[10][10];

 pr_row(0, 10, (int *) num); /* печать 1-й строки */

}

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

Задание

1. Следующая таблица представляет содержимое частичного индекса

Ключ               Номер сегмента

13С08                          1

23G19                          2

26Х28                          3

36Z05                          4

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

1

24Х17

2

12N67

3

32E75

4

26X28

5

17G37

6

24E43

7

15H42

8

21C32

9

35K51

10

27E45

11

13C08

12

29X11

13

34Z28

14

25X23

15

23X07

16

28L11

17

21G24

18

35X30

19

29Z20

20

33C29

2.Написать программу на языке C++, осуществляющую создание индексированного файла с вымышленными данными о студентах в количестве 20 человек: номер по журналу, ФИО, возраст.

Порядок выполнения работы

Ключ               Номер сегмента

13С08                          1

23G19                          2

26Х28                          3   

36Z05         4

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

ключевое значение-15F20

номер сегмента будет равен 2

Требования к отчету

Отчет должен содержать:

  1.  Исходное задание.
  2.  Описание алгоритмов.
  3.  Листинг программы.
  4.  Скриншоты результатов работы программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

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

Лабораторная работа № 28.

Хэширование данных

Цель

Формирование навыков в организации данных с использованием хэш – функций.

Задание для самостоятельной подготовки

  1.  Изучить основные положения хэширования данных [1], стр. 397-403.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Хэширование (hashing) — это процесс получения индекса элемента массива непосредственно в результате операций, производимых над ключом, который хранится вместе с элементом или даже совпадает с ним. Генерируемый индекс называется хэш-адресом (hash). Традиционно хэширование применяется к дисковым файлам как одно из средств уменьшения времени доступа. Тем не менее, этот общий метод можно применить и с целью доступа к разреженным массивам. В предыдущем примере с массивом указателей использовалась специальная форма хэширования, которая называется прямая адресация. В ней каждый ключ соответствует одной и только одной ячейке массива[1]. Другими словами, каждый индекс, вычисленный в результате хэширования, уникальный. (При представлении разреженного массива в виде массива указателей хэш-функция не должна обязательно реализовывать прямую адресацию — просто это был очевидный подход к реализации электронной таблицы.) В реальной жизни схемы прямого хэширования встречаются редко; обычно требуется более гибкий метод. В данном разделе показано, как можно обобщить метод хэширования, придав ему большую мощь и гибкость.

В примере с электронной таблицей понятно, что даже в самых сложных случаях используются не все ячейки таблицы. Предположим, что почти во всех случаях фактически занятые ячейки составляют не более 10 процентов потенциально доступных мест. Это значит, что если таблица имеет размер 260x100 (2`600 ячеек), в любой момент времени будет использоваться лишь примерно 260 ячеек. Этим подразумевается, что самый большой массив, который понадобится для хранения всех занятых ячеек, будет в обычных условиях состоять только из 260 элементов. Но как ячейки логического массива сопоставить этому меньшему физическому массиву? И что происходит, когда этот массив переполняется? Ниже предлагается одно из возможных решений.

Когда пользователь вводит данные в ячейку электронной таблицы (т.е. заполняет элемент логического массива), позиция ячейки, определяемая по ее имени, используется для получения индекса (хэш-адреса) в меньшем физическом массиве. При выполнении хэширования физический массив называется также первичным массивом. Индекс в первичном массиве получается из имени ячейки, которое преобразуется в число, точно так, как и в примере с массивом указателей. Но затем это число делится на 10, в результате чего получается начальная точка входа в первичный массив. (Помните, что в данном случае размер физического массива составляет только 10 % размера логического массива.) Если ячейка физического массива по этому индексу свободна, в нее заносятся логический индекс и данные. Но поскольку 10 логических позиций соответствуют одной физической позиции, могут возникнуть коллизии при вычислении хэш-адресов[2]. Когда это происходит, записи сохраняются в связанном списке, иногда называемом списком коллизий (collision list). С каждой ячейкой первичного массива связан отдельный список коллизий. Конечно, до возникновения коллизии эти списки имеют нулевую длину, как показано на рис. 23.3.

           Указатель

              на

            список

   Индекс  коллизий

  +------+----------+   +--+    +--+

0 |  А1  |     -------->|B1|--->|C1|

  +------+----------+   +--+    +--+

1 |  L1  |     -------->|P1|

  +------+----------+   +--+

2 |  А2  |   NULL   |

  +------+----------+

3 |  M2  |   NULL   |

  +------+----------+

4 |      |   NULL   |

  +------+----------+  Порядок

  |      .          |  поступления:

  |      .          |            A1

  |      .          |            L1

  +------+----------+            B1

258|  А1  |   NULL   |            C1

  +------+----------+            P1

259|  А1  |   NULL   |            A2

  +------+----------+            M2

   Первичный массив

Рисунок 1 – Пример хзширования

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

В примере хэширования используется массив структур под названием primary:

#define MAX 260

struct htype {

 int index;   /* логический индекс */

 int val;     /* собственно значение элемента данных */

 struct htype *next; /* указатель на следующий элемент с таким же

                        хэш-адресом */

} primary[MAX];

Перед использованием этого массива необходимо его инициализировать. Следующая функция присваивает полю index значение -1 (значение, которое по определению никогда не будет сгенерировано в качестве индекса); это значение обозначает пустой элемент. Значение NULL в поле next соответствует пустой цепочке хэширования[3].

/* Инициализация хэш-массива. */

void init(void)

{

 register int i;

 for (i=0; i<MAX; i++) {

   primary[i].index = -1;

   primary[i].next = NULL;  /* пустая цепочка */

   primary[i].val = 0;

 }

}

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

/* Вычисление хэш-адреса и сохранение значения. */

void store(char *cell_name, int v)

{

 int h, loc;

 struct htype *p;

 /* Получение хэш-адреса */

 loc = *cell_name - 'A'; /* столбец */

 loc += (atoi(&cell_name[1])-1) * 26; /* строка * ширина + столбец */

 h = loc/10; /* hash */

 /* Сохранить в полученной позиции, если она не занята

    либо если логические индексы совпадают - то есть, при обновлении.

 */

 if(primary[h].index==-1 || primary[h].index==loc) {

   primary[h].index = loc;

   primary[h].val = v;

   return;

 }

 /* в противном случае, создать список коллизий

    либо добавить в енго элемент */

 p = (struct htype *) malloc(sizeof(struct htype));

 if(!p) {

   printf("Не хватает памяти\n");

   return;

 }

 p->index = loc;

 p->val = v;

 slstore(p, &primary[h]);

}

/* Добавление элементов в список коллизий. */

void slstore(struct htype *i,

            struct htype *start)

{

 struct htype *old, *p;

 old = start;

 /* найти конец списка */

 while(start) {

   old = start;

   start = start->next;

 }

 /* связать с новой записью */

 old->next = i;

 i->next = NULL;

}

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

/* Вычисление хэш-адреса и получение значения. */

int find(char *cell_name)

{

 int h, loc;

 struct htype *p;

 /* получение значения хэш-адреса */

 loc = *cell_name - 'A'; /* столбец */

 loc += (atoi(&cell_name[1])-1) * 26; /* строка * ширина + столбец */

 h = loc/10;

 /* вернуть значение, если ячейка найдена */

 if(primary[h].index == loc) return(primary[h].val);

 else { /* в противном случае просмотреть список коллизий */

   p = primary[h].next;

   while(p) {

     if(p->index == loc) return p->val;

     p = p->next;

   }

   printf("Ячейки нет в массиве\n");

   return -1;

 }

}

Создание функции удаления оставлено читателю в качестве упражнения. (Подсказка: Просто обратите процесс вставки.)

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

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

Задание

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

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

Формат ключа

Количество сегментов

Метод хэширования

(разрешения коллизий)

AавсВС

2000

Линейное опробование

Где «а,в,с» – это цифры 0…9; «A,В,С» – это большие буквы латиницы A…Z.

Требования к отчету

Отчет должен содержать:

  1.  Исходные задания варианта.
  2.  Описание алгоритмов.
  3.  Листинг программы.
  4.  Скриншоты результатов работы программы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Порядок выполнения работы

Экспериментальное исследование проводится следующим образом:

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

Листинг программы 1. Формирование экспериментальных данных.

#include<iostream>

#include<fstream>

#include<string>

#include<ctime>

usingnamespace std;

#define b 2000

int h(char*);

int main()

{

char current_key[7]={NULL};

int A[b];

int adress=0;

srand((unsigned)time(0));

for(int i=0;i<b;i++)

 A[i]=0;

for(int i=0;i<b*3;i++)

{

 for(int j=0;j<6;j++)

 {

  if((j>0)&&(j<4))

   current_key[j]=(char)(rand()%10+48);

  else

   current_key[j]=(char)(rand()%26+65);

 }

 adress=h(current_key);

 A[adress]++;

}

ofstream os("result.txt");

for(int i=0;i<b;i++)

 os<<A[i]<<endl;

os.close();

return 0;

}

int h(char current_key[6])

{

int h=0,sum=0;

for(int i=0;i<6;i++)

 sum+=(int)((((int)current_key[i])/(3*(i+1))))*(int)current_key[i];

sum*=sum*2;

sum=sum % 1000000;

h=(int)(sum/100);

do

{

 h=h % b;

}

while(h>b);

returnh;

}

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

Рисунок 1 –Диаграмма распределения данных

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

Ниже приведена программа, реализующая следующие режимы:

  1.  Рандомное генерирование хэш-таблицы на основе заданной хэш-функции(таблица специально сгенерирована так, чтобы оставались промежутки: это даст возможность добавлять в таблицу данные, таблица сохраняется в файле Table.txt)
  2.  Добавление элементов
  3.  Поиск элементов
  4.  Удаление элементов[1]

Листинг программы 2. Работа с хэш – таблицей.

#include<iostream>

#include<fstream>

#include<string>

#include<windows.h>

#include<ctime>

usingnamespace std;

#define b 2000

string Tab[b];

int adress=0;

int h(char[7]);

void input(char[7]);

void add();

void find();

void del();

void create_table();

void output_in_file();

int main()

{

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

string smth;

for(int i=0;i<b;i++)

{

 Tab[i]="";

}

for(;;)

{

 system("cls");

 cout<<"МЕНЮ"<<endl<<endl<<"1. Рандомноегенерированиехэш-таблицы"<<endl<<"2. Добавление элемента"<<endl<<"3. Поиск элемента"<<endl<<"4. Удаление элемента"<<endl<<"5. Выход из программы"<<endl;

 cin>>smth;

 if(smth=="1")

  create_table();   

 else

 {

  if(smth=="2")

   add();

  else

  {

   if(smth=="3")

    find();

   else

   {

    if(smth=="4")

     del();

    else

    {

     if(smth=="5")

      exit(0);

     else

     {

      cout<<"Вводить нужно цифру от 1 до 5 включительно!"<<endl;

      system("pause");

     }

    }

   }

  }

 }

}

return 0;

}

int h(char key[7])

{

int h=0,sum=0;

for(int i=0;i<6;i++)

 sum+=(int)((((int)key[i])/(3*(i+1))))*(int)key[i];

sum*=sum*2;

sum=sum % 1000000;

h=(int)(sum/100);

do

{

 h=h % b;

}

while(h>b-1);

return h;

}

void input(char key[7])

{

bool correct=true;

char smth[256];

do

{

 cin>>smth;

 if(smth[6]!=NULL)

 {

  correct=false;

   cout<<"Введенные данные некорректны. Введите еще раз:"<<endl;

  continue;

 }

 else

 {

  for(int i=0;i<7;i++)

   key[i]=smth[i];

 }

 for(int i=0;i<6;i++)

 {

  if((i>0)&&(i<4))

  {

   if(((int)key[i]<48)||((int)key[i]>57))

   {

    correct = false;

     cout<<"Введенные данные некорректны. Введите еще раз:"<<endl;

    break;

   }

  }

  else

  {

   if(((int)key[i]<65)||((int)key[i]>90))

   {

    correct = false;

     cout<<"Введенные данные некорректны. Введите еще раз:"<<endl;

    break;

   }

  }

  if(i==5)

   correct=true;

 }

}

while(correct==false);

}

void add()

{

char key[7]={NULL};

bool correct = true;

system("cls");

do

{

 if(correct==true)

  cout<<"Введитеключформата «AцццAA», где"<<endl<<"«ц» – этоцифра 0…9;"<<endl<<"«A» – этобольшаябуквалатиницы A…Z."<<endl;

 input(key);

 adress=h(key);

 correct=true;

 while((Tab[adress]!="")&&(correct==true))

 {

  if(Tab[adress]==key)

   correct=false;

  else

   adress+=2;

 }

 if(correct==false)

  cout<<"Такое значение уже есть в таблице, введите другое!"<<endl;

 }

while(correct==false);

adress=h(key);

do

{

 if((Tab[adress]=="")||(Tab[adress]=="deleted"))

 {

  Tab[adress]=key;

  break;

 }

 else

  adress+=2;

 

}

while(adress<b-1);

if(adress>=b)

 cout<<"данные в таблицу добавить нельзя по одной из причин:"<<endl<<" Таблица переполнена"<<endl;

else

{

 cout<<"Данные добавлены в таблицу"<<endl<<endl<<"..."<<endl;

 for(int i=0;i<11;i++)

 {

  if(adress-(5-i)<0)

   continue;

  if(i==5)

   cout<<endl<<adress<<" "<<Tab[adress]<<endl<<endl;

  else

   cout<<adress-(5-i)<<" "<<Tab[adress-(5-i)]<<endl;

 }

 cout<<"..."<<endl<<endl;

}

output_in_file();

system("pause");

}

void find()

{

char key[7]={NULL};

bool correct = true;

int try_count=0;

system("cls");

cout<<"Введитеключформата «AцццAA», где"<<endl<<"«ц» – этоцифра 0…9;"<<endl<<"«A» – этобольшаябуквалатиницыA…Z."<<endl;

input(key);

adress=h(key);

bool flag=false;

do

{

 if(Tab[adress]==key)

 {

  flag=true;

  break;

 }

 else

 {

  if(Tab[adress]=="")

   break;

  else

   adress+=2;

 }

}

while(adress<b-1);

if(flag==false)

 cout<<"Элементненайден"<<endl;

else

{

 cout<<"Элементнайден!"<<endl<<endl<<"..."<<endl;

 for(int i=0;i<11;i++)

 {

  if(adress-(5-i)<0)

   continue;

  if(i==5)

   cout<<endl<<adress<<" "<<Tab[adress]<<endl<<endl;

  else

   cout<<adress-(5-i)<<" "<<Tab[adress-(5-i)]<<endl;

 }

 cout<<"..."<<endl<<endl;

}

system("pause");

}

void del()

{

char key[7]={NULL};

bool correct = true;

int try_count=0;

system("cls");

cout<<"Введитеключформата «AцццAA», где"<<endl<<"«ц» – этоцифра 0…9;"<<endl<<"«A» – этобольшаябуквалатиницыA…Z."<<endl;

input(key);

adress=h(key);

bool flag=true;

do

{

 if(Tab[adress]==key)

 {

  Tab[adress]="deleted";

  break;

 }

 else

 {

  if(Tab[adress]=="")

  {

   flag=false;

   break;

  }

  else

   adress+=2;

 }

}

while(adress<b-1);

if(adress>=b)

 flag=false;

if(flag==false)

 cout<<"Элементненайден"<<endl;

else

{

 cout<<"Элементудален!"<<endl<<endl<<"..."<<endl;

 for(int i=0;i<11;i++)

 {

  if(adress-(5-i)<0)

   continue;

  if(i==5)

   cout<<endl<<adress<<" "<<Tab[adress]<<endl<<endl;

  else

   cout<<adress-(5-i)<<" "<<Tab[adress-(5-i)]<<endl;

 }

 cout<<"..."<<endl<<endl;

}

output_in_file();

system("pause");

}

void create_table()

{

char key[7]={NULL};

int adress=0;

bool correct=true;

srand((unsigned)time(0));

for(int i=0;i<b-100;i++)

{

 for(int j=0;j<6;j++)

 {

  if((j>0)&&(j<4))

   key[j]=(char)(rand()%10+48);

  else

   key[j]=(char)(rand()%26+65);

 }

 adress=h(key);

 if((Tab[adress]=="")||(Tab[adress]=="deleted"))

  Tab[adress]=key;

 else

  continue;

}

output_in_file();

}

void output_in_file()

{

ofstream ofs("Table.txt");

for(int i=0;i<b;i++)

{

 ofs<<i<<"   "<<Tab[i]<<endl;

 }

ofs.close();

}

Контрольные вопросы

  1.  Каков принцип построения хэш-таблиц?
  2.  Существуют ли универсальные методы построения хэш-таблиц? Ответ обоснуйте.
  3.  Почему возможно возникновение коллизий?
  4.  Каковы методы устранения коллизий? Охарактеризуйте их эффективность в различных ситуациях.
  5.  Назовите преимущества открытого и закрытого хэширования.
  6.  В каком случае поиск в хэш-таблицах становится неэффективен?
  7.  Как выбирается метод изменения адреса при повторном хэшировании?

Лабораторная работа № 29.

Создание таблиц баз данных

Цель

Формирование навыков создания базы данных.

Задание для самостоятельной подготовки

  1.  Изучить основы организации и функционирования баз данных [1], стр. 410-444.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

База данных – это хранилище структурированных данных, при этом данные должны быть непротиворечивы, минимально избыточны и целостны.

База данных — совместно используемый набор логически связанных данных (и описание этих данных), предназначенный для удовлетворения информационных потребностей организации.

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

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

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

Иерархические базы данных. Иерархические базы данных графически могут быть представлены как дерево, состоящее из объектов различных уровней. Верхний уровень занимает один объект, второй — объекты второго уровня и т. д.

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

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

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

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

С понятием базы данных тесно связано понятие системы управления базой данных или СУБД. Это комплекс программных средств, предназначенных для создания структуры новой базы, наполнения ее содержимым, редактирования содержимого и визуализации информации. Под визуализацией информации базы данных понимается отбор отображаемых данных в соответствии с заданным критерием, их упорядочение, оформление и последующая выдача на устройство вывода или передача по каналам связи. ПримерыСУБД: MS Access, Oracle, MS SQL, Interbase, Sybase, MySQLит.д.

На сегодняшний день существует множество СУБД. Несмотря на то, что они могут по-разному работать с разными объектами и предоставляют пользователю различные функции и средства, большинство СУБД опираются на единый устоявшийся комплекс основных понятий. Это дает возможность рассмотреть одну систему и обобщить ее понятия, приемы и методы на весь класс СУБД. В качестве такого учебного объекта выбрана СУБД MicrosoftAccess.

Access — это реляционная СУБД. Это означает, что с ее помощью можно работать одновременно с несколькими таблицами базы данных. Применение реляционной СУБД помогает упростить структуру данных и таким образом облегчить выполнение работы. Таблицу Access можно связать с данными, хранящимися на другом компьютере  или на сервере, а также использовать таблицу, созданную в СУБД Paradox или pbase. Данные Access очень просто комбинировать с данными Excel. В СУБД Access предусмотрено много дополнительных сервисных возможностей.Мощность и гибкость системы Access делают ее сегодня одной из лучших программ для управления базами данных.

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

  •  Имя поля – определяет, как следует обращаться к данным этого поля при автоматических операциях с базой (по умолчанию имена полей используются в качестве заголовков столбцов таблиц).
    •  Тип поля – определяет тип данных, которые могут содержаться в данном поле.
    •  Размер поля – определяет предельную длину (в символах) данных, которые могут размещаться в данном поле.
    •  Формат поля – определяет способ форматирования данных в ячейках.
    •  Маска ввода – определяет форму, в которой вводятся данные в поле.
    •  Подпись – определяет заголовок столбца таблицы для данного поля (если подпись не указана, то в качестве заголовка столбца используется свойство Имя поля).
    •  Значение по умолчанию – то значение, которое вводится в ячейки поля автоматически (средство автоматизации ввода данных).
    •  Условие на значение – ограничение, используемое для проверки правильности ввода данных (средство автоматизации ввода, которое используется, как правило, для данных, имеющих числовой тип, денежный тип или тип даты).
    •  Сообщение об ошибке – текстовое сообщение, которое выдается автоматически при попытке ввода в поле ошибочных данных (проверка ошибочности выполняется автоматически, если задано свойство Условие на значение).
    •  Обязательное поле – свойство, определяющее обязательность заполнения данного поля при наполнении базы.
    •  Пустые строки – свойство, разрешающее ввод пустых строковых данных (от свойства Обязательноеполе отличается тем, что относится не ко всем типам данных, а лишь к некоторым, например, к текстовым).
    •  Индексированное поле – если поле обладает этим свойством, все операции, связанные с поиском или сортировкой записей по значению, хранящемуся в данном поле, существенно ускоряются. Кроме того, для индексированных полей можно сделать так, что значения в записях будут проверяться по этому полю на наличие повторов, что позволяет автоматически исключить дублирование данных.

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

  •  Текстовый – тип данных, используемый для хранения обычного неформатированного текста ограниченного размера (до 255 символов).
    •  Поле Мемо – специальный тип данных для хранения больших объемов текста (до 65 535 символов). Физически текст не хранится в поле. Он хранится в другом месте базы данных, а в поле хранится указатель на него, но для пользователя такое разделение заметно не всегда.
    •  Числовой – тип данных для хранения действительных чисел.
    •  Дата/время – тип данных для хранения календарных дат и текущего времени.
    •  Денежный – тип данных для хранения денежных сумм. Теоретически, для их записи можно было бы пользоваться и полями числового типа, но для денежных сумм есть некоторые особенности (например, связанные с правилами округления), которые делают более удобным использование специального типа данных, а не настройку числового типа.
    •  Счетчик – специальный тип данных для уникальных (не повторяющихся в поле) натуральных чисел с автоматическим наращиванием. Естественное использование – для порядковой нумерации записей.
    •  Логический – тип для хранения логических данных (могут принимать только два значения, например, «Да» или «Нет»).
    •  Поле объекта OLE– специальный тип данных, предназначенный для хранения объектов, например, мультимедийных, вставляемых внедрением или связыванием (OLE). Реально такие объекты в таблице не хранятся. Как и в случае полей Memo, они хранятся в другом месте внутренней структуры файла базы данных, а в таблице хранятся только указатели на них (иначе работа с таблицами была бы чрезвычайно медленной).
    •  Гиперссылка – специальное поле для хранения адресов URLWeb-объектов Интернета. При щелчке на ссылке автоматически происходит запуск браузера и воспроизведение объекта в его окне.
    •  Мастер подстановок – это не специальный тип данных. Это объект, настройкой которого можно автоматизировать ввод данных в поле так, чтобы не вводить их вручную, а выбирать из раскрывающегося списка.

Кроме таблиц, база данных может содержать и другие типы объектов. Основные типы объектов СУБД MicrosoftAccess.

Таблицы. Это основные объекты любой базы данных. В таблицах хранятся все данные, имеющиеся в базе. Кроме того, таблицы хранят и структуру базы – поля, их типы и свойства.

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

Формы. Если запросы – это специальные средства для отбора и анализа данных, то формы – это средства для ввода данных, хотя с их помощью данные можно и просматривать. Формы нужны для того, чтобы предоставить пользователю средства для заполнения только тех полей, которые ему заполнять положено. Преимущества форм очевидны, например, когда происходит ввод данных с заполненных бланков. В этом случае форма делается графическими средствами такой, чтобы она повторяла оформление бланка, – это заметно упрощает работу.С помощью форм данные можно не только вводить, но и отображать. Запросы тоже отображают данные, но делают это в виде результирующей таблицы стандартного вида. А при выводе данных с помощью форм можно применять специальные графические средства оформления.

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

Задание

Вариант 1

«Лекарства в таблетках»

1. Сведения: название, фирма, страна, цена, кол-во упаковок, дата выпуска, срок годности, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

2. Создать таблицу с помощью запроса: вывести название препаратов стоимостью менее 20 рублей.

3. Создать следующие запросы:

a) вывести Названия лекарств, цена на которые более 20 рублей ;

b) вывести Названия всех отечественных лекарств.

Вариант 2

«Сотрудники»

1.Сведения: фамилия, имя, отчество, должность (заполняется из справочника должностей), размер заработной платы,  дата рождения, о семейном положении (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

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

3.Создать следующие запросы:

a) вывести фамилии всех сотрудников, получающих более 1600 рублей;

b) вывести фамилии и должности сотрудников, которым нет 18 лет.

Вариант 3

«Туалетная вода»

1. Сведения: название, тип (жен., муж.), дата выпуска, срок годности, страна, цена, фирма-производитель, число упаковок, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

2. Создать таблицу с помощью запроса: вывести название туалетной воды , произведенной во Франции.

3. Создать следующие запросы:

a) вывести названия всех типов туалетной воды для мужчин;

b) вывести название  туалетной воды, цена которой менее 100 рублей.

Вариант 4

«Склад»

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

2. Создать таблицу с помощью запроса: вывести наименование товаров с минимальной партией более 50.

3. Создать следующие запросы:

a)      вывести наименование и количество всех товаров, хранящихся на  складе;

b)      вывести  прайс- лист.

Вариант 5

«Фильмотека»

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

2. Создать таблицу с помощью запроса: названия фильмов ,вышедших на экран за последние 3 года.

3. Создать следующие запросы:

a) вывести названия всех фильмов, в которых снимался данный актер;

b) вывести фамилию режиссера, снявшего данный фильм.

Вариант 6

«Погода в мире»

1. Создать первую таблицу, содержащую следующие сведения: Дата, температура, облачность, осадки, регион (заполняется из справочника регионов).

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

3. Создать таблицу с помощью запроса: вывести даты, когда температура была в интервале от (0,-5) градусов.

4. Создать следующие запросы:

a) вывести даты, когда шел снег и температура ниже -10 градусов;

b) вывести сведения о погоде в данном регионе.

Вариант 7

«Бюро занятости»

1. Сведения: ФИО безработного, профессия, образование, возраст, пол, стаж, о семейном положении безработного (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

2. Создать таблицу с помощью запроса: вывести фамилии всех женщин со стажем более 10 лет.

3. Создать следующие запросы:

a) вывести фамилии всех учителей со стажем более 2 лет;

b) вывести профессии безработных с высшим образованием.

Вариант 8

«Вкладчики банка»

1. Сведения: ФИО вкладчика, номер счета, пароль, размер вклада, размер кредита, о семейном положении вкладчика (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

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

3. Создать следующие запросы:

a) вывести фамилии всех вкладчиков, размер вклада, которых не превышает 1000 рублей;

b) вывести пароль данного вкладчика.

Вариант 9

«Владельцы машин»

1. Сведения: ФИО владельца, номер машины, марка машины, цвет, адрес владельца, о семейном положении владельца (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

2. Создать таблицу с помощью запроса: вывести фамилии владельцев российских машин .

3. Создать следующие запросы:

a) вывести фамилии всех владельцев серебристых «иномарок»;

b) вывести фамилии и адреса владельцев автомашин с номерами, начинающимися на 35.

Вариант 10

«Теннисисты»

1. Сведения: фамилия и имя теннисиста, название турнира, место на турнире, рейтинг (номер ракетки в мире), о семейном положении теннисиста (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

2. Создать таблицу с помощью запроса: фамилии теннисистов из стран Европы

3. Создать следующие запросы:

a) вывести фамилии всех призеров Уимблдона;

b) вывести фамилии и имена теннисистов, входящих в  первую 10.

Вариант 11

«Мои любимые музыкальные группы»

1. Сведения:  название группы, год создания группы, стиль, фамилия солиста, самый популярный альбом: название альбома, год  выпуска, тираж альбома, о семейном положении солиста (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

2. Создать таблицу с помощью запроса: вывести названия групп и альбомов тиражом более 1000.

3. Создать следующие запросы:

a) вывести фамилию солиста конкретной группы;

b) напечатать названия групп и названия альбомов, популярных в течении последних 5 лет.

Вариант 12

«Моя кулинария»

1. Сведения: название блюда, энергетическая ценность (ккал), цена, о рецептуре блюда (продукт, количество, цена).

2. Создать таблицу с помощью запроса: перечислить блюда, энергетическая  ценность которых превышает 100 Ккал.

3. Создать следующие запросы:

a) вывести названию блюд, энергетическая ценность которых не превышает 100 Ккал.;

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

Вариант  13

«Студенты»

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

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

3.Создать следующие запросы:

a) вывести фамилии всех студентов, не допущенных к сессии;

b) вывести фамилии и номера групп отличников.

Вариант  14

«Хиты месяца»

1. Сведения: название песни, композитор, поэт, исполнитель, дата I-го исполнения, город, о семейном положении композитора (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

2. Создать таблицу с помощью запроса: вывести названия всех песен, впервые исполненных  за последние 2 года.

3.Создать следующие запросы:

a) вывести даты исполнения песен одного композитора;

b) вывести названия вех песен , исполненных впервые в Москве.

Вариант  15

«Музыка на CD»

1. Сведения: название, автор, исполнитель, число произведений (песен, пьес, арий и т.д.), дата выпуска, тираж, стоимость, формат, о семейном положении автора (ФИО родственника, вид родства (заполняется из справочника родственных связей), дата рождения).

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

3. Создать следующие запросы:

a) вывести  прайс-лист;

b) вывести авторов и исполнителей с дисков, выпуска последних 2 лет.

Вариант  16

«Кремы для лица»

1. Сведения: название крема, дата выпуска, срок годности , для какого типа кожи (ж,с,н),  страна, фирма, стоимость, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

2. Создать таблицу с помощью запроса: вывести названия всех кремов, со сроком годности более года.

3. Создать следующие запросы:

a) вывести названия кремов для нормальной и сухой кожи лица;

b) вывести страну и фирму производителя для кремов дороже 80 рублей.

Вариант  17

«Детская косметика»

1. Сведения: название, вид, дата выпуска, срок годности, фирма-производитель, страна, стоимость, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

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

3. Создать следующие запросы:

a) вывести названия всех кремов и их стоимость;

b) вывести названия вех средств, произведенных в России.

Вариант  18

«Библиотека»

1.Сведения: название книги, автор, год издания, издательство, цена, количество книг, об издательствах (страна, город (заполняется из справочника городов), телефон).

2.Создать таблицу с помощью запроса: названия книг, изданные за последние 3 года.

3.Создать следующие запросы:

a) вывести названия всех книг, цена на которые > 50 рублей;

b) вывести названия всех книг данного автора.

Вариант  19

«Лекарства в ампулах»

1. Сведения:  название, фирма, страна, цена, число упаковок, дата выпуска, срок годности, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

2. Создать таблицу с помощью запроса: вывести название   отечественных  лекарств с числом упаковок  более 100.

3. Создать следующие запросы:

a) вывести названия лекарств, цена на которые менее 30 рублей ;

b) вывести названия всех лекарств со сроком годности более  года.

Вариант  20

«Магазин женской обуви»

1. Сведения: вид (туфли, сапоги, босоножки), цвет, размер, фирма, страна, цена, о продукции фирмы-производителя (название продукта (заполняется из справочника наименований продукции), количество, цена).

2. Создать таблицу с помощью запроса: вывести все виды обуви с ценою более 1000 рублей.

3. Создать следующие запросы:

a) вывести виды обуви, размером более 37 отечественного производства;

b) вывести страну и фирму всех светлых босоножек.

Порядок выполнения работы

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

Таблица 1 – Атрибуты сущностей БД студентов факультета

Сущность

Атрибуты

Студенты

ФИО студента

Группа

Специальность

Телефон

Дисциплины

Код дисциплины

Название дисциплины

ФИО преподавателя

Литература

Методические материалы

План учебного процесса

Название дисциплины

Код дисциплины

Всего часов

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

Расписание занятий

Номер группы

Дни недели

Время занятий

Название дисциплины

Вид занятия

Аудитория

Преподаватель

Успеваемость

ФИО студента

Название дисциплины

Оценка

Сущности вступают во взаимоотношения, называемые связями. Наиболее распространены связи «многие – ко - многим» и «один – ко - многим». Сущность Расписание занятий имеет с сущностью СТУДЕНТЫ связь «один – ко - многим», поскольку по одному расписанию учебных занятий учится много студентов (рис.1):

Рисунок 1 – Концептуальная модель базы данных

Сущность СТУДЕНТЫ имеет с сущностью Успеваемость связь «один – ко - многим», так как понятие «успеваемость студента» представляет совокупность его оценок по нескольким предметам. Сущность план учебного процесса имеет связь с сущностью ДИСЦИПЛИНА типа «один – ко - многим», поскольку учебный процесс – это временная характеристика изучения целого ряда дисциплин. Аналогичная связь и между сущностью план учебного процесса и сущностью УСПЕВАЕМОСТЬ, которые также вступают в связь «один – ко - многим», так как по каждой дисциплине, изучаемой в ходе учебного процесса, получают оценки несколько студентов.

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

  1.  Создать по одной таблице для каждой сущности;
  2.  Для каждой сущности, выступающей во взаимоотношениях с другими сущностями как «один – ко - многим» или «один – к - одному», указать один столбец в качестве первичного ключа;
  3.  Задать первичный ключ для каждой сущности, выступающей во взаимоотношениях как «многие – к - одному».

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

Таблицы Студенты, Расписание занятий и План учебного процессаимеют в своем составе уникальное для каждой строки поле — это соответственно ФИО студента, Номер группы и Дисциплина. Исходя из этого, назначаем эти поля в качестве первичных ключей. В связующем отношении между таблицей Успеваемость и таблицами План учебного процесса и Студенты атрибуты ФИО студента и Дисциплина образуют составной ключ. Эти атрибуты представляют собой внешние ключи, являющиеся первичными ключами других отношений.

Рисунок 2 – Логическая модель базы данных (жирным отмечены первичные ключи)

Вследствие указанных назначений и определений первичных ключей между таблицами Студенты и Успеваемость, План учебного процесса и Успеваемость обеспечивается связь «один – ко – многим». Атрибут Номер группы является первичным ключом таблицы Расписание занятий и внешним ключом таблицы Студенты. Данное обстоятельство обеспечивает связь «один – ко – многим» между вышеназванными таблицами.

Таблице Дисциплины в качестве первичного ключа назначается некоторый уникальный числовой идентификатор записи Код дисциплины. Этот атрибут, являясь внешним ключом таблицы План учебного процесса обеспечивает связь «один – к - одному» между таблицами Дисциплины и План учебного процесса.

Создать БД можно следующими способами:

  •  пустую неструктурированную БД;
  •  пустую структурированную БД на основе шаблона.

БД включает в себя различные объекты (таблицы, формы, запросы, отчеты), предназначенные для ввода, управления и хранения информации. Все объекты одной БД хранятся в одном и том же файле, имеющем стандартное расширение .accdb, который не поддерживается предыдущими версиями Access.

Основой БД является таблица,столбец которой называется полем,а строка — записью.

Форма позволяет более наглядно отобразить информацию, содержащуюся в одной записи БД.

Запросы предназначены для поиска и получения информации из БД по различным критериям. Макрос— последовательность макрокоманд для расширения возможностей СУБД. С их помощью можно изменять ход выполнения приложения, открывать, фильтровать и изменять данные в формах и отчетах, выполнять запросы и создавать новые таблицы.

Модуль — объект, содержащий программы на языке VisualBasic.

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

Основу базы данных составляют таблицы. Создать таблицу можно несколькими способами:

  •  в режиме Конструктор;
  •  с помощью Мастера таблиц;
  •  в режиме Таблица;
  •  с помощью импортирования;
  •  с помощью связывания с другими БД.

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

Рисунок 3 – Связи между таблицами созданной базы данных

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Ход разработки базы данных.
  4.  Ответы на контрольные вопросы
  5.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что называется базой данных (БД)?
  2.  Что такое система управления базами данных (СУБД)?
  3.  Какие объекты базы данных MicrosoftAccess вы знаете?
  4.  Какой объект в базе данных является основным?
  5.  Что называется полями и записями в БД?
  6.  Какие типы данных вы знаете?
  7.  С каким расширением сохраняется файл БД Access?

Лабораторная работа № 30.

«Управление данными»

Цель

Формирование необходимых представлений и навыков о способах организации и основах работы с таблицами баз данных.

Задания для самостоятельной подготовки

  1.  Познакомиться с основами работы MSAccess[11], 63-195.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Реляционная база данных — база данных, основанная на реляционной модели данных. Слово «реляционный» происходит от англ. relation (отношение). Для работы с реляционными БД применяют реляционные СУБД. Целью нормализации реляционной базы данных является устранение недостатков структуры базы данных, приводящих к вредной избыточности в данных, которая в свою очередь потенциально приводит к различным аномалиям и нарушениям целостности данных.

Для выполнения основных операций с базами данных служат инструментальные пакеты программ, которые называются системами управления базами данных (СУБД). Для хранения информации о группе однородных объектов в большинстве современных СУБД используется таблица базы данных. СУБД и соответствующие им базы данных, хранение информации в которых основано на таблицах, принято называть реляционными (от relation–отношение). Дело в том, что математическая структура, соответствующая таблице, называется отношением.

Например, информацию о сотрудниках некоторой фирмы можно представить в виде отношения, приведенного на рисунке 1.

Рисунок 1 – Отношение, содержащее информацию о сотрудниках

Строка в отношении называется кортежем (tuple). В отношении, представленном на рисунке 1, каждый кортеж содержит информацию об одном сотруднике. Столбцы в отношении именуются атрибутами (attribute), поскольку каждый элемент столбца описывает некоторую характеристику (или атрибут) одной  сущности, представленной соответствующим кортежем. В нашем примере каждый кортеж содержит атрибуты Emplld (Личный номер работника), Name (Имя и фамилия), Address (Адрес) и SSNum (Номер полиса социального страхования).

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

NEW <- SELECT from EMPLOYEE where Emplld = "34Y70"

Семантика этого выражения — создать новое отношение с именем NEW,  содержащее те кортежи (в приведенном случае он будет единственным) отношения EMPLOYEE, в которых значение атрибута Emplld равно "34Y70" (рисунок 2).

Рисунок 2 – Операция SELECT

В противоположность операции выборки SELECT, которая извлекает из  отношения строки, операция проекции PROJECT предназначена для извлечения столбцов. Ниже приведен еще один пример использования операции PROJECT:

MAIL<- PROJECTName, AddressfromEMPLOYEE

Эта операция позволяет получить список имен и адресов всех сотрудников компании. Искомый список содержится во вновь созданном отношении с именем MAIL, с двумя атрибутами Name и Address (рисунок 3).

Рисунок 3 – Операция PROJECT

Третьей операцией, с которой мы здесь познакомимся, является операция соединения JOIN. Она предназначена для объединения данных из двух разных отношений. Соединение двух отношений посредством операции JOIN приводит к созданию нового отношения, набор атрибутов которого включает все атрибуты исходных отношений (рисунок 4). Имена атрибутов нового отношения не отличаются от имен атрибутов исходных отношений, за  исключением того, что перед каждым из них в качестве префикса, отделяемого точкой, указывается имя исходного отношения. (Если отношение А содержит атрибуты V и W, а отношение В — атрибуты X, Y и Z, то полученное в  результате их соединения отношение будет содержать атрибуты A.V, A.W, B.X, B.Y и B.Z.) Кортежи (строки) нового отношения образуются посредством конкатенации кортежей двух исходных отношений (рисунок 4). Для того чтобы определить,  какие именно строки из исходных отношений должны быть объединены, в  операции JOIN задается некоторое условие. Одним из вариантов такого условия  является задание пары атрибутов исходных отношений, значения в которых должны совпадать. Именно этот вариант условия представлен на рисунке 4, который  демонстрирует механизм выполнения следующего оператора:

С <- JOIN A and В where A.W = B.X

Рисунок 4 – Операция JOIN

В качестве примера для ознакомления с простейшими возможностями баз данных и СУБД рассмотрим некоторые возможности программы MicrosoftAccess, которая является одной из самых сложных составных частей пакета MicrosoftOffice.

СУБД MSAccessпредназначена для создания и поддержания в рабочем состоянии баз данных, для получения из них информации в требуемой форме, а также для создания приложений, автоматизирующих работу с базами данных. База данных в программе MSAccessпредставляет собой взаимосвязанную совокупность основных компонентов, которые называются объектами базы. Объектами базы данных в MSAccessсчитаются таблицы, формы, запросы, отчеты, а также страницы, макросы и модули.

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

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

Задания к работе

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

  1.  о композиторах, их биографиях и произведениях;
  2.  об исполнителях музыкальных произведений, их записях и композиторах, чью музыку они записывали;
  3.  о производителях компьютерного оборудования и их продуктах;
  4.  об издательствах, выпускаемых ими журналах и количестве подписчиков;
  5.  об автомобильных запчастях, составляющих их деталях и изготовителях;
  6.  о книгах, их авторах и издательствах, которые их выпускали;
  7.  об авиалиниях, их рейсах и расписании полетов;
  8.  о магазинах и ассортименте их товаров;
  9.  о производителях автомобилей, выпускаемых ими моделях и ценах на них;
  10.  о странах, количестве их населения и занимаемой площади;
  11.  о футбольных клубах, их главных тренерах и составах;
  12.  об Олимпийских играх, местах их проведения и странах-участницах;
  13.  о планетах и их спутниках;
  14.  о болезнях, их симптомах и средствах профилактики;
  15.  о реках, их географическом положении и бассейнах;
  16.  о сотрудниках компании, их должностях и отделах, в которых они работают;
  17.  о видах спорта и соревнованиях по ним;
  18.  о телевизорах, их характеристиках и производителях;
  19.  о городах, количестве их населения и странах, в состав которых они входят;
  20.  о видах птиц и местах их обитания.

Порядок выполнения работы

  1.  Изучить основы теории по теме лабораторной работы.
  2.  Подобрать необходимыйматериал для представления в базе данных информации, указанной в вашем варианте.
  3.  С помощью  MSAccessсоздать базу данных, наиболее наглядно представляющую подобранный материал.

Отчет о работе

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Исходные данные по заданному варианту лабораторной работы.
  3.  Описание хода выполнения работы.
  4.  Результат выполнения работы.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

  1.  Что представляет собой система управления базами данных?
  2.  Какие базы данных и СУБД  относят к реляционным?
  3.  Назовите основные реляционные операции и опишите их.
  4.  Как связаны между собой различные отношения в реляционной базе данных?
  5.  Для чего предназначена СУБД MSAccess?

Лабораторная работа № 31.

Машины и интеллект

Цель

Формирование представления об основах создания и функционирования искусственного интеллекта.

Задание на самостоятельную подготовку

1. Изучить теоретические основы  формирования искусственного интеллекта [1], стр. 447 – 465.

2. Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Если мы хотим создать машины, которые смогут решать сложные задачи без человеческого вмешательства, необходимо сделать машины более похожими на людей в том смысле, чтобы они обладали возможностью (или, по крайней мере, имитировали возможность) рассуждать. Осознав это требование, специалисты по вычислительной технике обратились к другим ученым — психологам и биологам — в надежде найти правила, которые можно применить к созданию более гибких компьютеров и программ. Теперь зачастую бывает трудно провести границу между исследованиями в этих новых областях и исследованиями, относящимися к вычислительной технике. Различие состоит скорее не в том, что уже сделано, но в целях. Например, психолог пытается глубже проникнуть в человеческий разум и узнать о процессах мышления, а ученый, специализирующийся на компьютерах, старается создать более умные машины.

Чтобы прояснить ситуацию, предположим, что специалист по вычислительной технике и психолог отдельно друг от друга приступили к работе над проектом по созданию программы для игры в покер. Компьютерный специалист захочет применить теорию вероятностей и статистику, чтобы получить программу, которая будет рассчитывать шансы, наугад блефовать, не выказывать эмоций и в результате максимизировать свои шансы на выигрыш. Психолог, с другой стороны, может разработать программу на основе теорий о человеческом мышлении и поведении. В результате проект может вылиться в создание нескольких различных программ; например, одна из них сможет играть агрессивно, а другую, напротив, можно будет легко запугать. В отличие от программы специалиста по компьютерам, программа психолога сможет «эмоционально втянуться» в игру и проиграть все свои средства.

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

Второе мнение разделял Алан Тьюринг, который в 1950 году разработал тест для оценки интеллекта машины. Предложение Тьюринга заключалось в том, что человек, который называется опрашивающим, общался с субъектом теста посредством системы ручного ввода текста, не зная, является ли этим субъектом тоже человек или машина. Интеллект машины признавался в случае, когда опрашивающий не мог определить, с кем он общался — с машиной или с человеком. Таким образом, тест Тьюринга оценивает способность машины быть похожей на человека. Тьюринг полагал, что к 2000 году у машин будет 30-процентный шанс пройти 5-минутный тест Тьюринга — и это предположение оказалось на удивление точным.

Известный пример сценария теста Тьюринга получился из программы DOCTOR (версии более общей системы под названием ELIZA), созданной Джозефом Вайзенбаумом в середине 60-х годов. Эта интерактивная программа представляла психологическое собеседование с психоаналитиком по фамилии Роджериан, причем компьютер играл роль доктора, а пользователь — пациента. На самом деле все, что делал DOCTOR — реструктурировал предложения, высказанные пациентом, согласно некоторым хорошо определенным правилам, и выводил их на экран. Например, на предложение «Я сегодня очень устал» DOCTOR мог ответить «Почему ты думаешь, что ты сегодня очень устал?» Если DOCTOR не мог распознать структуру предложения, он просто отвечал что-то типа «Продолжай» или «Очень интересно».

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

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

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

Рисунок 1 – Машина для решения головоломки

Рисунок 2 - Головоломка

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

Для выполненияпоставленной задачи, необходимо пройти 3 шага:

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

а) сравнение частей картинки

б) сравнение геометрических характеристик

2) Анализ.На данном этапе, машине предстоит выяснить, что представляют из себя эти компоненты, а в конечном итоге всё изображение.

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

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

1) Набор состояний

а)Начальное состояние (стартовое)

б) Целевое состояние (конечное)

2) Набор порождений – операции, выполняющие перемещение из одного состояние в другое.

3) Система управления

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

Граф состояний.Важная составляющая разработки системы управления — граф состояний. Это удобный способ представления всех состояний, порождений и входных условий продукционной системы. Термин «граф» обозначает структуру, которую математики называют направленным графом, что означает, что набор положений, называемых узлами, соединен стрелками. Граф состояний состоит из узлов, представляющих состояния системы, соединенных стрелками, обозначающими порождения, которые переводят систему из одного состояния в другое. Два узла соединены стрелкой в графе состояний тогда и только тогда, когда в продукционной системе существует порождение, преобразующее систему из состояния в начале стрелки в состояние в конце стрелки. Входные условия неявно представляются отсутствием стрелок между определенными узлами.

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

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

Рисунок 3 – Дерево поиска для задачи

Задание

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

Вариант

Головоломка

1

2

3

6

7

4

8

1

5

2

5

3

4

8

6

7

2

1

3

3

4

5

1

6

2

8

7

4

4

1

3

5

2

7

8

6

5

5

8

7

4

2

1

3

6

6

3

2

7

8

5

6

1

4

7

6

1

2

7

3

5

4

8

8

2

1

4

7

8

6

5

3

9

4

7

1

5

2

3

8

6

10

5

6

4

1

7

2

3

8

11

6

4

1

4

2

8

5

7

12

2

1

3

8

7

4

6

5

13

5

8

1

4

2

6

7

3

14

3

4

5

6

2

1

7

8

15

2

7

1

3

8

5

6

4

16

2

5

1

4

7

3

6

8

17

5

1

6

4

2

7

3

8

18

3

7

1

2

4

8

5

1

19

4

1

2

7

6

3

8

5

20

3

5

1

2

6

4

8

7

Пример выполнения задания

Если имеется такая головоломка:

1

3

5

4

2

7

6

8

то дерево поиска будет выглядет следующим образом:

Контрольные вопросы

  1.  Растение в темной комнате с единственным источником света растет по направлению к этому источнику. Можно ли считать это интеллектуальной реакцией? Можно ли считать растение  разумным?
  2.  Если машины прошла тест Тьюринга, согласитесь ли вы, что машина разумная? Если нет, согласитесь ли вы, что она кажется разумной?
  3.  В чем различия между требованиями к видеосистеме робота в случаях, когда изображение используется роботом для управления собственными действиями и когда эти образы передаются человеку, который удалённо управляет роботом?
  4.  Какое значение имеют продукционные системы для искусственного интеллекта?
  5.  Что такое дерево поиска?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу-таблицу.
  4.  Описание машины Тьюринга в каждом из состояний.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа № 32.

Искусственныенейронные сети

Цель

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

Задание для самостоятельной подготовки

  1.  Изучить основные свойства искусственных нейронных сетей[1], стр. 465-479.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

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

Искусственные нейронные сети (ИНС) строятся по принципам организации и функционирования их биологических аналогов.

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

В 50-х годах прошлого века группа исследователей объединила биологические и физиологические подходы и создала первые искусственные нейронные сети. Тогда казалось, что ключ к искусственному интеллекту найден. Но, хотя эти сети эффективно решали некоторые задачи из области искусственного зрения — предсказания погоды и анализа данных, иллюзии вскоре рассеялись. Сети были не в состоянии решать другие задачи, внешне похожие на те, с которыми они успешно справлялись. С этого времени начался период интенсивного анализа. Были построены теории, доказан ряд теорем. Но уже тогда стало понятно, что без привлечения серьезной математики рассчитывать на значительные успехи не следует.

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

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

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

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

Рисунок 1 - Взаимосвязь биологических нейронов

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

Синапс является элементарной структурой и функциональным узлом между двумя нейронами (волокно аксона одного нейрона и дендрит другого).

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

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

В большинстве нейронных моделей тип нейрона связан с егорасположением в сети. Если нейрон имеет только выходные связи,то это входной нейрон, если наоборот - выходной нейрон.

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

• полносвязные (рисунок2, а);

• многослойные или слоистые (рисунок 2, б);

• слабосвязные (с локальными связями) (рисунок 2, в).

Рисунок 2 – Архитектуры нейронных сетей:

а -полносвязные;

б-многослойная сеть с последовательными связями;

в - слабосвязные связи.

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

В многослойных нейронных сетях нейроны объединяются в слои. Слой содержит совокупность нейронов с едиными входными сигналами. Число нейронов в слое может быть любым и не зависит от количества нейронов в других слоях. В общем случае сеть состоит из Q слоев, пронумерованных слева направо. Внешние входные сигналы подаются на входы нейронов входного слоя (его часто нумеруют как нулевой), а выходами сети являются выходные сигналы последнего слоя. Кроме входного и выходного слоев в многослойной нейронной сети есть один или несколько скрытых слоев. Связи от выходов нейронов некоторого слоя q к входам нейронов следующего слоя (q+1) называются последовательными.

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

  •  Монотонные;
  •  Сети без обратных связей;
  •  Сети с обратными связями.

В слабосвязных нейронных сетях нейроны располагаются в узлах прямоугольной или гексагональной решетки. Каждый нейрон связан с четырьмя (окрестность фон Неймана), шестью (окрестность Голея) или восемью (окрестность Мура) своими ближайшими соседями.

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

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

Таблица 1-Задача распознавания рукописных букв в нейронной сети

Задача распознавания рукописных букв

Дано растровое черно-белое изображение буквы размером 30x30 пикселов

Необходимо распознать предъявленную букву (в алфавите 33 буквы)

Формулировка задачи для нейронной сети

Дано входной вектор из 900 двоичных символов (900 = 30x30)

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

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

Нейронная сеть строится в два этапа:

  1.  Выбор типа (архитектуры) сети;
  2.  Подбор весов (обучение) сети.

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

  •  какие нейроны использовать (число входов, функции активации);
  •  каким образом следует соединить нейроны между собой;
  •  что взять в качестве входов и выходов сети.

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

Обучить нейронную сеть это значит, сообщить ей чего от нее добиваются. Процесс обучения заключается в последовательном предъявлении букв(рисунок 3).

Рисунок 3 – Процесс обучение нейронной сети

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

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

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

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

  •  Массовый параллелизм;
  •  Распределённое представление информации и вычисления;
  •  Способность к обучению и обобщению;
  •  Адаптивность;
  •  Свойство контекстуальной обработки информации;
  •  Толерантность к ошибкам;
  •  Низкое энергопотребление.

Чтобы понять потенциал искусственных нейронных сетей, рассмотримпроблему распознавания символов на примере заглавных букв С и Т, показанных на рисунке4. Задача заключается в идентификации букв, помещенных в поле зрения, независимо от их ориентации. Все шаблоны на рисунке5а должны быть распознаны как буква С, а все шаблоны в части б представляют букву Т.

Рисунок 4 – Заглавная С и заглавная Т

Мы начнем с предположения что поле зрения состоит из квадратных пикселов, каждый из которых равен квадратным элементам, из которых составлены буквы. Каждый пиксел присоединен к датчику, который выдает 1, если пиксел закрыт просматриваемой буквой, и 0 — в противном случае. Выходы этих датчиков мы используем как входы нашей искусственной нейронной сети.

Сеть (рисунок6) состоит из блоков обработки данных двух уровней. Первый уровень составляет множество блоков — по одному для каждой области размером 3x3 пиксела в поле зрения. Для каждого из этих блоков существует девять входов, с которыми связаны датчики областей 3x3. (Обратите внимание, что области, связанные с обрабатывающими блоками первого уровня, перекрывают друг друга, поэтому каждый датчик является входом для девяти блоков обработки данных первого уровня.)

Рисунок 5 – Различные расположения букв С и Т

Рисунок 6 – Структура системы распознавания символов

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

Для каждого модуля обработки данных на первом уровне также установлено пороговое значение 0,5. Для каждого из входов вес задан равным 1 кроме входа связанного с центральным пикселом области 3x3 этого модуля для которого вес равен 2. Таким образом, каждый из этих модулей может выдать единицу, только если получит единицу от датчика, связанного с пикселом в центре области 3x3.

Теперь, если буква С расположена в поле зрения (рисунок 7), все обрабатывающие модули первого уровня выдадут значение 0. Это происходит потому, что в областях 3x3 всех блоков, центральный пиксел которых закрыт буквой, есть, по крайней мере, еще два других пиксела, также закрытых буквой, и сигналы, полученные от их датчиков, уменьшают значение сигнала центрального пиксела. Следовательно, если в поле зрения находится буква С, все входы обрабатывающего блока второго уровня равны 0, и выход всей сети также равен нулю.

Рисунок 7 – Буква С в поле зрения

Рассмотрим ситуацию с буквой Т в поле зрения. Представим себе область 3x3, центр которой — квадрат, закрытый нижней частью ножки буквы Т(рисунок8). Обрабатывающий блок, связанный с этим квадратом, получит эффективный вход, равный 1 (2 от центрального пиксела и 1 от остальных пикселов, закрытых ножкой). Это превышает пороговое значение блока, поэтому он отправит единицу

Рисунок 8 – Буква Т в поле зрения

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

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

Задание

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

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

Исходные данные

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Порядок выполнения работы

Рассмотримраспознавание символов на примере заглавных букв С и Т, показанных на рисунке9. Задача заключается в идентификации букв, помещенных в поле зрения, независимо от их ориентации. Все шаблоны на рисунке10а должны быть распознаны как буква С, а все шаблоны в части б представляют букву Т.

Рисунок 9 – Заглавная С и заглавная Т

Начнем с предположения что поле зрения состоит из квадратных пикселов, каждый из которых равен квадратным элементам, из которых составлены буквы. Каждый пиксел присоединен к датчику, который выдает 1, если пиксел закрыт просматриваемой буквой, и 0 — в противном случае. Выходы этих датчиков мы используем как входы нашей искусственной нейронной сети.

Сеть (рисунок11) состоит из блоков обработки данных двух уровней. Первый уровень составляет множество блоков — по одному для каждой области размером 3x3 пиксела в поле зрения. Для каждого из этих блоков существует девять входов, с которыми связаны датчики областей 3x3. (Обратите внимание, что области, связанные с обрабатывающими блоками первого уровня, перекрывают друг друга, поэтому каждый датчик является входом для девяти блоков обработки данных первого уровня.)

Рисунок 10 – Различные расположения букв С и Т

Рисунок 11 – Структура системы распознавания символов

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

Для каждого модуля обработки данных на первом уровне также установлено пороговое значение 0,5. Для каждого из входов вес задан равным 1 кроме входа  связанного с центральным пикселом области 3x3 этого модуля для которого вес равен 2. Таким образом, каждый из этих модулей может выдать единицу, только если получит единицу от датчика, связанного с пикселом в центре области 3x3.

Теперь, если буква С расположена в поле зрения (рисунок 12), все обрабатывающие модули первого уровня выдадут значение 0. Это происходит потому, что в областях 3x3 всех блоков, центральный пиксел которых закрыт буквой, есть, по крайней мере, еще два других пиксела, также закрытых буквой, и сигналы, полученные от их датчиков, уменьшают значение сигнала центрального пиксела. Следовательно, если в поле зрения находится буква С, все входы обрабатывающего блока второго уровня равны 0, и выход всей сети также равен нулю.

Рисунок 12 – Буква С в поле зрения

Рассмотрим ситуацию с буквой Т в поле зрения. Представим себе область 3x3, центр которой — квадрат, закрытый нижней частью ножки буквы Т(рисунок13). Обрабатывающий блок, связанный с этим квадратом, получит эффективный вход, равный 1 (2 от центрального пиксела и 1 от остальных пикселов, закрытых ножкой). Это превышает пороговое значение блока, поэтому он отправит единицу

Рисунок 13 – Буква Т в поле зрения

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

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

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу-таблицу.
  4.  Описание машины Тьюринга в каждом из состояний.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Контрольные вопросы

1) Предположим, что торговый автомат должен выдавать различные продукты в зависимости от того, какая кнопка нажата. Можно ли сказать, что такая машина «знает», какая из кнопок нажата? Каково в таком случае ваше определение осведомленности?

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

3) Какое значение имеют продукционные системы для искусственного интеллекта?

4) Сколько кубиков составляют следующую фигуру? Каким образом можно запрограммировать машину, чтобы она точно ответила на этот вопрос?

Лабораторная работа №33.

«Машины Тьюринга. Вычислимые и невычислимые функции»

Цель

Формирование представления об основах функционирования машины Тьюринга

Задание для самостоятельной подготовки

  1.  Изучить устройство и основные принципы функционирования машины Тьюринга [1], стр.499-517.
  2.  Изучить содержание и порядок выполнения лабораторной работы.

Основы теории

Машина Тьюринга состоит из управляющего блока, который может считывать и выводить символы на ленту при помощи головки считывания-записи (рис. 1). Лента продолжается до бесконечности с обеих сторон машины и разделена на ячейки, каждая из которых может содержать только один символ из конечного набора символов. Этот набор называется машинным алфавитом.

Рисунок 1 – Компоненты машины Тьюринга

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

Работа машины Тьюринга состоит из последовательности шагов, которые выполняет управляющий блок машины. Каждый шаг заключается в считывании символа из текущей ячейки ленты, записи символа в эту ячейку, перемещении головки считывания-записи на одну ячейку влево или вправо и последующей перемене состояния. Действие, которое требуется выполнить, определяется программой, которая отдает приказы управляющему блоку. Она основывается на состоянии машины и содержимом текущей ячейки ленты.

Рассмотрим последовательность действий машины Тьюринга на конкретном примере.Будем представлять ленту машины в виде горизонтальной полоски, разделенной на ячейки, куда можно записывать символы машинного алфавита. Указывать текущее положение головки считывания-записи машины мы будем, помещая указатель под соответствующую ячейку, которую будем называть текущей ячейкой. Алфавит в нашем примере состоит из символов 0, 1 и *. Лента машины может выглядеть следующим образом:

Рисунок 2 – Лента машины Тьюринга

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

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

У нашей машины есть состояния:«начало», «прибавить», «перенос», «переполнение», «возврат» и «останов». Действия, соответствующие каждому из этих состояний, и содержимое текущих ячеек перечислены в табл.1. Мы предполагаем, что машина всегда начинает работу из состояния «начало».

Таблица 1 – Машина Тьюринга для увеличения значения на единицу

Текущее состояние

Текущее содержимое ячейки

Значение для записи

Направление перемещения

Переход в состояние

Начало

*

*

Влево

Прибавить

Прибавить

0

1

Вправо

Возврат

Прибавить

1

0

Влево

Перенос

Прибавить

*

*

Вправо

Останов

Перенос

0

1

Вправо

Возврат

Перенос

1

0

Влево

Перенос

Перенос

*

*

Влево

Переполнение

Переполнение

Любое

*

Вправо

Возврат

Возврат

0

0

Вправо

Возврат

Возврат

1

1

Вправо

Возврат

Возврат

*

*

Не двигаться

Останов

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

Рисунок 3 – Лента машины Тьюринга в состоянии «прибавить»

Для продолжения работы посмотрим в таблице 1, что следует делать в состоянии «прибавить» с единицей в текущей ячейке. Таблица говорит нам заменить 1 в текущей ячейке на 0, передвинуть головку считывания-записи на одну ячейку влево и войти в состояние «перенос».

Рисунок 4 – Лента машины Тьюринга в состоянии «перенос»

Мы снова обращаемся к таблице 1 за дальнейшими указаниями и обнаруживаем, что в состоянии «перенос», если в текущей ячейке содержится 0, необходимо заменить 0 на 1, переместить головку считывания-записи на одну ячейку вправо и войти в состояние «возврат».

Рисунок 5 – Лента машины Тьюринга в состоянии «возврат»

В этой ситуации таблица говорит нам, что следует заменить 0 в текущей ячейке на 0, передвинуть головку считывания-записи на одну ячейку вправо и остаться в состоянии «возврат».

Рисунок 6 – Состояние машины Тьюринга после замены

Теперьследует переписать звездочку в текущей ячейке и войти в состояние «останов». Таким образом, машина останавливается в нужной конфигурации, т.е символы на ленте представляют значение 6.

Рисунок 7 – Результат работы машины Тьюринга

Машину Тьюринга из предыдущего примера можно применять для вычисления функции, известной как функция следования, которая каждому неотрицательному целому входному значению n ставит в соответствие выходное значение n + 1. Необходимо всего лишь поместить входное значение в бинарной форме на ленту машины, запустить машину, дождаться ее остановки и считать выходное значение с ленты. Функция, которую можно вычислить подобным образом на машине Тьюринга, называется вычислимой по Тьюрингу (Turingcomputable).

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

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

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

while X not 0

do:

incr X;

end;

Если мы запустим эту программу с начальным значением переменной X, равным нулю, цикл выполняться не будет, и программа вскоре завершится. Если же начальное значение X будет отличаться от нуля, цикл будет выполняться бесконечно, и процесс окажется непрерывным.

В этом случае легко сделать вывод, что выполнение программы прекратится только в случае, если запущена она была со значением X, равным 0. Однако если мы рассмотрим более сложные программы, задача предсказания их поведения существенно усложнится.

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

Рассмотрим, что произойдет, если выполнить его для простой программы(1):

while X not 0

do;

incr X;

end;

Мы хотим узнать, что произойдет, если запустить эту программу, присвоив переменной X закодированный вариант самой программы (рис. 8). В этом случае ответ очевиден. Так как значение X не равно нулю, программа попадет в цикл и никогда не остановится. С другой стороны, если выполнить подобный эксперимент над программой(1), то она остановится, так как независимо от начального значения на момент достижения структуры while-end значением переменной X будет ноль.

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

Рисунок 8 – Тестирование программы на самозавершение

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

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

Теперь следует показать, что решение проблемы останова выходит за пределы возможностей машин. Мы будем исходить из того, что для решения задачи потребуется алгоритм вычисления невычислимой функции. Входами этой функции являются закодированные варианты программ на скелетном языке, а выходами — значения 0 и 1. Для краткости мы будем называть эту функцию функцией останова.

Наша задача — продемонстрировать, что функция останова является невычислимой. Следует доказать, что утверждение «функция останова вычислима» не может быть правдой. Доказательство продемонстрировано на рис.9.

Рисунок 9 – Доказательство неразрешимости проблемы останова

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

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

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

while X not 0 do;

end;

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

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

Если же новая программа не самозавершающаяся, и мы запустим ее, присвоив переменным закодированное значение программы, она достигнет добавленного оператора while со значением X, равным 0. (Это происходит потому, что операторы, предшествующие оператору while, генерируют выход программы, равный 0, если на вход подана кодировка несамозавершающейся программы). В этом случае цикл while-end не будет выполнен, и программа остановится. Но это свойство самозавершающейся программы, поэтому мы делаем вывод, что новая программа самозавершающаяся, так же, как ранее увидели, что она не является самозавершающейся.

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

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

Задание

Разработать машину Тьюринга, определяющую деление десятичного числа на число, равное вашему порядковому номеру в журнале, без остатка. Десятичное число записано на ленте машины. Если делится, то записать справа от числа слово “да”, иначе — “нет”. Кроме самой программы-таблицы, описать словами, что выполняется машиной в каждом состоянии.

Порядок выполнения работы

Дана строка из букв «a» и «b». Разработать машину Тьюринга, которая переместит все буквы «a» в левую, а буквы «b» — в правую части строки. Автомат в состоянии q1 обозревает крайний левый символ строки. Кроме самой программы-таблицы, описать словами, что выполняется машиной в каждом состоянии.

Решение этой задачи обычно вызывает затруднение. Рассмотрим следующие варианты просмотра входных слов:

aaa —> выходное слово совпадает с входным, просматриваем входное слово до тех пор, пока оно не заканчивается.

a —> выходное слово совпадает с входным, просматриваем входное слово до тех пор, пока оно не заканчивается.

bbb —> выходное слово совпадает с входным, просматриваем входное слово до тех пор, пока оно не заканчивается.

b —> выходное слово совпадает с входным, просматриваем входное слово до тех пор, пока оно не заканчивается.

ab —> выходное слово совпадает с входным, просматриваем входное слово до тех пор, пока оно не заканчивается.

Машина Тьюринга должна «понимать», по цепочке каких букв она идет, т.е. у нее должно быть как минимум два состояния. Пусть состояние q1 — движение по цепочке из букв «a», а q2 — состояние движения по цепочке из букв «b». Заметим, что цепочка может состоять и из одной буквы. Если мы дошли до конца строки в состоянии q1 или q2, т.е. встретили a0, машина должна остановиться, мы обработали всю строку.

Рассмотрим следующие варианты входных слов:

bba —>abb

bbbaab —>aabbbb

aabbbaab —>aaaabbbb

Первый вариант входного слова можно последовательно обработать следующим образом: bba —>bbb —> вернуться к левому концу цепочки из букв «b» —>abb (заменить первую букву в этой цепочке на «a»). Для выполнения этих действий нам потребуется ввести два новых состояния и, кроме того, уточнить состояние q2. Таким образом, для решения этой задачи нам нужно построить машину Тьюринга со следующими состояниями:

q1 — идем вправо по цепочке букв «a». Если цепочка заканчивается a0, то переходим в q0; если заканчивается буквой «b», то переходим в q2;

q2 — идем вправо по цепочке букв «b», если цепочка заканчивается a0, то переходим в q0; если заканчивается «a», то заменяем букву «a» на «b», переходим в состояние q3 (цепочку вида  заменили на цепочку вида );

q3 — идем влево по цепочке букв «b» до ее левого конца. Если встретили a0 или «a», то переходим в q4;

q4 — заменяем «b» на «a» и переходим в q1 (цепочку вида заменяем на цепочку вида)

Рисунок 10 – Результат выполнения работы (программа-таблица)

Контрольные вопросы

  1.  Какие составные части включает в себя машина Тьюринга?
  2.  Какие основные принципы работы машины Тьюринга?
  3.  Какие состоянияимеются у машины Тьюринга? Перечислите их.
  4.  В чем заключается тезис Черча-Тьюринга?
  5.  Что подразумевается под термином «невычислимая функция»?
  6.  В чем состоит проблема останова?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Программу-таблицу.
  4.  Описание машины Тьюринга в каждом из состояний.
  5.  Ответы на контрольные вопросы.
  6.  Выводы о проделанной работе.

Лабораторная работа №33

Алгоритмы криптографической защиты информации

Цель

Изучить основы алгоритмов криптографической защиты информации.

Задание для самостоятельной подготовки

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

Основы теории

Криптография  — наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним) и аутентичности (целостности и подлинности авторства, а также невозможности отказа от авторства) информации. Изначально криптография изучала методы шифрования информации — обратимого преобразования открытого (исходного) текста на основе секретного алгоритма и/или ключа в шифрованный текст (шифротекст). Традиционная криптография образует раздел симметричных криптосистем, в которых шифрование и расшифрование проводится с использованием одного и того же секретного ключа. Помимо этого раздела современная криптография включает в себя асимметричные криптосистемы, системы электронной цифровой подписи (ЭЦП), хеш-функции, управление ключами, получение скрытой информации, квантовую криптографию.

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

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

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

Криптографическая система с открытым ключом (или Асимметричное шифрование, Асимметричный шифр) — система шифрования и/или электронной цифровой подписи (ЭЦП), при которой открытый ключ передаётся по открытому (то есть незащищённому, доступному для наблюдения) каналу и используется для проверки ЭЦП и для шифрования сообщения. Для генерации ЭЦП и для расшифровки сообщения используется секретный ключ. Криптографические системы с открытым ключом в настоящее время широко применяются в различных сетевых протоколах.

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

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

Понять идеи и методы криптографии с открытым ключом помогает следующий пример — хранение паролей в компьютере. Каждый пользователь в сети имеет свой пароль. При входе он указывает имя и вводит секретный пароль. Но если хранить пароль на диске компьютера, то кто-нибудь его может считать (особенно легко это сделать администратору этого компьютера) и получить доступ к секретной информации. Для решения задачи используется односторонняя функция. При создании секретного пароля в компьютере сохраняется не сам пароль, а результат вычисления функции от этого пароля и имени пользователя. Например, пользователь Алиса придумала пароль «Гладиолус». При сохранении этих данных вычисляется результат функции (ГЛАДИОЛУС), пусть результатом будет строка РОМАШКА, которая и будет сохранена в системе.

В результате файл паролей примет следующий вид:

Имя (имя-пароль)

АЛИСА РОМАШКА

БОБ НАРЦИСС

Вход в систему теперь выглядит так: Имя: АЛИСА

Пароль: ГЛАДИОЛУС

Когда Алиса вводит «секретный» пароль, компьютер проверяет, даёт или нет функция, применяемая к ГЛАДИОЛУС, правильный результат

РОМАШКА, хранящийся на диске компьютера. Стоит изменить хотя бы одну букву в имени или в пароле, и результат функции будет совершенно другим. «Секретный» пароль не хранится в компьютере ни в каком виде. Файл паролей может быть теперь просмотрен другими пользователями без потери секретности, так как функция практически необратимая.

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

Для каждой буквы из шифруемого сообщения выбирается имя, начинающееся на ту же букву. Таким образом букве ставится в соответствие номер телефона абонента. Отправляемое сообщение, например «КОРОБКА», будет зашифровано следующим образом:

Сообщение Выбранное имя Криптотекст

К Королёв 5643452

О Орехов 3572651

Р Рузаева 4673956

O Осипов 3517289

Б Батурин 7755628

К Кирсанова 1235267

А Арсеньева 8492746

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

Примеры таких криптотекстов:

Криптотекст 1 Криптотекст 2 Криптотекст 3

1235267          5643452          1235267

3572651          3517289          3517289

4673956          4673956          4673956

3517289          3572651          3572651

7755628          7755628          7755628

5643452          1235267          5643452

8492746          8492746          8492746

Чтобы расшифровать текст, надо иметь справочник, составленный согласно возрастанию номеров. Этот справочник является лазейкой (секрет, который помогает получить начальный текст), известной только легальным пользователям. Не имея на руках копии справочника, криптоаналитик затратит очень много времени на расшифровку.

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

Шифрование при помощи задачи о ранце

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

191 691 573 337 365 730 651 493 177 354

так, чтобы их сумма была равна 2063.

Наиболее известный способ решения задачи о ранце заключается в последовательной проверке всех возможных комбинаций чисел, пока не будет найдено решение. Но если в списке п значений, проверить придется 2" комбинаций. Поэтому, если только нам не посчастливится найти правильную комбинацию в начале поиска, время, необходимое для решения, будет очень большим. Чтобы самостоятельно понять эту особенность, попробуйте решить приведенную ранее задачу о ранце. Вы обнаружите, что это займет много времени, хотя список состоит всего из 10 значений. Представьте свое замешательство, если вам будет дано 20 значений, то есть более миллиона комбинаций для проверки.

Популярные системы шифрования

Одна из наиболее популярных систем шифрования, используемая для безопасной передачи данных в Интернете, — это PGP (Pretty Good Privacy), которую разработал Филипп Циммерман в 1991 году. PGP — простая в использовании система шифрования общего назначения с открытым ключом, бесплатно распространяемая в Интернете для некоммерческого использования. Алгоритм, на основе которого разработана PGP, — это RSA, названный в честь его создателей: Рона Райвеста (Ron Rivest), Ади Шамира (Adi Shamir) и Леонарда Адлемана (Leonard Adleman). В отличие от систем шифрования, основанных на сложности решения задачи о ранце, которые мы обсуждаем в этом разделе, RSA основана на сложности поиска множителей больших целых чисел. RSA является примером того, как патентное право и государственное регулирование влияют на распространение программного обеспечения. Действительно, за RSA велось множество патентных битв, и правительство США продолжает ограничивать ее распространение. Подробнее об этой грандиозной эпопее вы можете узнать, найдя соответствующие документы в Сети. Для начала стоит вам поискать узлы, посвященные PGP и RSA.

Задание

(выбрать вариант равный номеру по списку в журнале)

Выбрать набор значений из списка так:

  1.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2063.
  2.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1957.
  3.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2036.
  4.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1788.
  5.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1820.
  6.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1809.
  7.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1952.
  8.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2005.
  9.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2026.
  10.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1413.
  11.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1935.
  12.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1795.
  13.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2182.
  14.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2025.
  15.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2239.
  16.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1966.
  17.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1917.
  18.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2072.
  19.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2490.
  20.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1533.
  21.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2479.
  22.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 1942.
  23.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2066.
  24.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2111.
  25.  191 691 573 337 365 730 651 493 177 354 чтобы их сумма = 2065.

Порядок выполнения работы

Задачу о ранце на основе приведенного выше списка можно применять для шифрования сообщений следующим образом: сначала представим сообщение в виде строки битов, возможно, используя ASCII или Unicode. Затем разобьем эту строку на сегменты по 10 битов и представим каждый 10-битовый сегмент в виде одного числа. Это число получается путем сложения значений из списка, занимающих места, соответствующие позициям единиц в 10-битовом сегменте. Например, 10-битовый сегмент 1ОО11О0ОО1 будет представлен числом 1247 (рис. 11.8): единицы в сегменте находятся на первой, четвертой, пятой и десятой позиции, а сумма соответствующих значений в списке (191, 337, 365 и 354) равна 1247. Аналогично, комбинация 0010011010 будет представлена числом 2131 (573 + 730 + + 651 + 177). Сообщение 1001100001001О011010 будет зашифровано последовательностью из двух чисел: 1247 и 2131.

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

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

Чтобы получить эту хитрость, заметим, что некоторые задачи о ранце решаются легко. Предположим, что список состоит из следующих значений: 1 4 6 12 24 51 105 210 421 850

Каждое число в списке больше суммы всех предшествующих чисел. Поэтому, если нам необходимо выбрать набор значений, сумма которых равна 995, мы будем точно знать, что одно из требуемых значений — это 850, так как сумма всех остальных значений будет слишком мала. Сделав этот выбор, мы сократим задачу до выбора чисел, сумма которых равна 995 - 850, то есть 145. Но это означает, что нужно обязательно выбрать 105, так как это самое близкое к искомому меньшее значение. Продолжая размышлять подобным образом, мы быстро сделаем вывод, что нужные нам значения — это 850, 105, 24, 12 и 4.

А теперь финальный аккорд: существует способ преобразования подобных простых задач о ранце в сложные задачи и обратно. Рассмотрим процесс преобразования в терминах трех «волшебных» чисел. Позже мы узнаем, откуда берутся эти волшебные числа и как построить собственную систему шифрования. Наши волшебные числа — это 642, 2311 и 18.

Первый шаг — преобразовать список

1 4 6 12 25 51 105 210 421 850

при помощи которого конструируется простая задача о ранце, в другой список, соответствующий более сложной задаче. Мы сделаем это, умножив каждое число из списка на 642 (первое магическое число) и записав остатки от деления произведений на 2311 (второе магическое число). В итоге получим список

642 257 1541 771 2184 388 391 782 2206 304

В частности, вместо значения 4 из исходного списка теперь стоит 257, так как 4 х 642 = 2568, а остаток от деления 2568 на 2311 равен 257.

Заметим, что задача о ранце в терминах нового списка будет сложнее, так как процесс преобразования разрушил отношения, существовавшие между значениями исходного списка. Но, зная волшебные числа, мы можем быстро решить новую задачу. Умножим целевую сумму на 18 (третье волшебное число), разделим результат на 2311 (второе волшебное число) и запишем остаток от деления. Затем будем считать этот остаток суммой нужных значений задачи о ранце с исходным «простым» списком. После того как эта простая задача будет решена, значения первого списка, решающие исходную задачу о ранце, будут значениями, которые занимают позиции, соответствующие решению простой задачи о ранце.

Например, наша задача — выбрать значения из списка

642 257 1541 771 2184 388 391 782 2206 304

сумма которых равна 4895. Сначала умножаем 4895 х 18 = 88 ПО, затем делим 88 110 на 2311, остаток равен 292. Затем определяем, что значения 6, 25, 51 и 210 — это значения из списка

1 4 6 12 25 51 105 210 421 850

дающие в сумме 292. Так как это третье, пятое, шестое и восьмое значения в соответствующем списке, делаем вывод, что третье, пятое, шестое и восьмое числа в списке

642 257 1541 771 2184 388 391 782 2206 304

дают в сумме 4895. Действительно, 1541 + 2184 + 388 + 782 - 4895, что и требовалось.

Полная система шифрования с открытым ключом работает следующим образом: мы свободно распространяем список

642 257 1541 771 2184 388 391 782 2206 304

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

Контрольные вопросы

  1.  Преимущества и недостатки криптосистемы с открытым ключом?
  2.  Применение алгоритмов криптосистемы с открытым ключом?
  3.  Виды симметричных и асимметричных шифров?
  4.  Параметры алгоритмов?

Требования к отчету

Отчет должен содержать:

  1.  Тему и цель работы.
  2.  Задание.
  3.  Алгоритм решения поставленной задачи.
  4.  Ответы на контрольные вопросы.
  5.  Выводы о проделанной работе.

Литература

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

Информатика [Электронный ресурс]: лекции к курсу: Часть 1./ Громов Ю.Ю. [и др.]. – Тамбов: Тамб. гос. техн. ун-т, 2007. - Режим доступа http://window.edu.ru/window_catalog/files/r56885/k_Gromov2.pdf/.

Зверев, Г.Н. Теоретическая информатика и ее основания [Электронный ресурс]: учеб. пособие для студентов втузов: в 2 т. / Г.Н. Зверев. - М.: Физматлиз, 2008.- Т.1,2. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2386/.

Кудинов, Ю.И. Основы современной информатики. [Электронный ресурс]: учеб. пособие для студентов вузов. / Ю.И. Кудинов, Ф.Ф. Пащенко. - М.: Лань, 2011. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2024/.

Кудинов, Ю.И. Практикум по основам современной информатики. [Электронный ресурс]: учеб. пособие для студентов вузов. / Ю.И. Кудинов, Ф.Ф. Пащенко, А.Ю. Келина. - М.: Лань, 2011. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1799/.

Дополнительная литература

Гладков, Л.А. Генетические алгоритмы. [Электронный ресурс]: учеб. / Л.А. Гладков, В.В. Курейчик, В.М. Курейчик. - М.: Физматлиз, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2163/.

Введение в теоретико-числовые методы криптографии: учеб. пособие для студентов вузов. [Электронный ресурс] / Глухов М.М. [и др.]. - М.: Лань, 2007. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1540/.

Дейл, Н. Программирование на С++. [Электронный ресурс] / Н. Дейл, Ч. Уимз, М. Хедингтон. - М: ДМК Пресс, 2007. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1219/.

Догадин Н.Б. Архитектура компьютера. [Электронный ресурс]: учеб. пособие для студентов вузов. / Н.Б. Догадин. - М.: БИНОМ. Лаборатория знаний, 2008. - Режим доступа http://window.edu.ru/window_catalog/files/r64584/Dogadin_978-5-94774-728-7/1-2-3_cB728-7.pdf/.

Ибе, О. Компьютерные сети и службы удаленного доступа. [Электронный ресурс] / О. Ибе. - М.: ДМК Пресс, 2007. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1169/.

Илюшечкин, В.М. Операционные системы [Электронный ресурс]: учеб. пособие для студентов вузов. / В.М. Илюшечкин. - М.: БИНОМ. Лаборатория знаний, 2009. - Режим доступа http://window.edu.ru/window_catalog/files/r65308/Ilyushechkin_978-5-94774-963-2/1-2-3_cB963-2.pdf/.

Кауфман, В.Ш. Языки программирования. Концепции и принципы. [Электронный ресурс] / В.Ш. Кауфман. - М: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1270/.

Курячий, Г.В. Операционная система Linux. [Электронный ресурс]: лекции к курсу / Г. В. Курячий, К.А. Маслинский. - М: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1202/.

Марченков, С.С. Рекурсивные функции. [Электронный ресурс]: бр. / С.С. Марченков. - М.: Физматлиз, 2007. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2260/.

Матрос, Д.Ш. Теория алгоритмов [Электронный ресурс]: учеб. / Д.Ш. Матрос, Г.Б. Поднебесова. - М.: БИНОМ. Лаборатория знаний, 2008. Режим доступа http://window.edu.ru/window_catalog/files/r64609/Matros_978-5-94774-226-8/1-2-3_cB226-8.pdf/.

Острейковский, В.А. Информатика. Теория и практика. [Электронный ресурс]: учеб. пособие для студентов вузов. / В.А. Острейковский, И.В. Полякова. - М.: Оникс, 2008. - Режим доступа http://www.knigafund.ru/books/42473/.

Паронджанов, В.Д. Дружелюбные алгоритмы, понятные каждому. [Электронный ресурс] / В.Д. Паронджанов. - М.: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1083/.

Петров, А.А. Компьютерная безопасность. Криптографические методы защиты. [Электронный ресурс] / А.А. Петров. - М.: ДМК Пресс, 2008. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=3027/.

Петрушин, В.Н. Информационная чувствительность компьютерных алгоритмов. [Электронный ресурс]: учеб. пособие для студентов вузов. / В.Н. Петрушин, М.В. Ульянов. - М.: Физматлиз, 2007. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2275/.

Потопахин, В.И. Искусство алгоритмизации. [Электронный ресурс] / В.И. Потопахин. М: ДМК Пресс, 2011. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1269/.

Ульянов, М.В. Ресурсно-эффективные компьютерные алгоритмы. Разработка и анализ. [Электронный ресурс]: учеб. пособие для студентов вузов. / М.В. Ульянов. - М.: Физматлиз, 2008. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=2354/.

Чекмарев, Ю.В. Локальные вычислительные сети. [Электронный ресурс]: учеб. пособие для студентов вузов. / Ю.В. Чекмарев. - М.: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1147/.

Чекмарев, Ю.В. Вычислительные системы, сети и телекоммуникации. [Электронный ресурс]: учеб. пособие для студентов вузов. / Ю.В. Чекмарев. - М.: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1146/.

Шаньгин, В.Ф. Защита компьютерной информации. [Электронный ресурс] / В.Ф. Шаньгин. - М.: ДМК Пресс, 2010. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=1122/.

Юдович, В.И. Математические модели естественных наук. [Электронный ресурс]: лекции к курсу. / В.И Юдович. - М.: Лань, 2011. Режим доступа http://e.lanbook.com/books/element.php?pl1_cid=25&pl1_id=689/.

Яшин, В.М. Информатика. [Электронный ресурс]: учеб. / В.М. Яшин. - М.: ИНФРА - М, 2008. - Режим доступа http://www.knigafund.ru/books/19100/

Периодическая литература

Журнал «CNews»

Журнал «CIO»

Журнал «ITСпец»

Журнал «КомпьютерПресс»

Internet-ресурсы

www.intuit.ru - Интернет-университет информационных технологий.

http://citforum.ru/ - Центр информационных технологий.

http://www.tstu.ru/r.php?r=education - Электронная библиотека ТГТУ.

http://www.edu.ru/  - Библиотека Федерального портала «Российское образование»

http://new.hse.ru/sites/infospace/podrazd/facul/facul_bi/opi/Lists /Discussion1/Attachments/339/ЕСПД%2019.001-19.701.pdf - Сборник стандартов ЕСПД


0

6

7

9

Индексы

i

imin

Массив:

а

1

2

3

Непрерывный блок ячеек памяти

Первое имя

хранится здесь

Второе имя

хранится здесь

Десятое имя

хранится здесь

Непрерывный блок ячеек памяти

Первое поле

хранится здесь

Второе поле

хранится здесь

Седьмоеполе

хранится здесь

Структура st1

Непрерывный блок ячеек памяти

Структура st2[0]

хранится здесь

Структура st2[1]

хранится здесь

Структура st2[9]

хранится здесь

Массив структурst2[10]

Поля  структур

Голова списка

INF

NEXT

NEXT

NF

INF

NULL

Голова списка

NULL

INF

NEXT

PREV

INF

NEXT

PREV

INF

NULL

Указатель конца

PREV

INF

NULL

PREV

INF

NEXT

Голова списка

NULL

INF

NEXT

head

p

item

newNode

head  указывает на p

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

head

item

NULL

newNode

newMode

currPtr

item

NULL

head

NextMode()

head

head

next

currPtr

prevPtr

key

60

65

74

82

newNode

head=currPtr

60

65

74

82

50

newNode

prevPtr

currPtr

70

60

65

74

82

newNode

prevPtr

90

60

65

74

82

Коробки

Push D

Pop

Push C

PushB

Push A

A

A

B

C

A

A

B

A

B

A

D

Pop

указатель головы

а

указатель хвоста

А

б

указатель головы

указатель хвоста

в

В

указатель хвоста

А

указатель головы

В

указатель головы

указатель хвоста

г

указатель хвоста

А

В

С

указатель головы

а

б

С

D

E

F

указатель головы

указатель хвоста

указатель головы

указатель хвоста

E

F

G

H

в

последняя ячейка блока

указатель хвоста

указатель головы

первая ячейка блока

N

O

G

F

H

I

J

K

L

M

Очередь перемещается в этом направлении

б

а

M

L

K

J

I

H

указатель хвоста

указатель головы

Очередь перемещается в этом направлении

последняя ячейка блока

первая ячейка блока

N

O

F

G

План

учебного процесса

Дисциплины

Студенты

Успеваемость

Расписание

занятий

1

1

1

Код дисциплины

Название дисциплины

ФИО преподавателя

Телефон

Литература

Методические материалы

ФИО студента

Номер группы

Специальность

Телефон

Номер группы

Понедельник

Вторник

Среда

Четверг

Пятница

Суббота

ФИО студента

Название

дисциплины

Оценка

Название

дисциплины

Код дисциплины

Всего часов

Практические

занятия

Экзамен

Зачет

КР

КП

План учебного

процесса

Дисциплины

Студенты

Успеваемость

Расписание занятий

1

1

1

1

1




1.  Назначение ТХ Устройство расположение и крепление ОПВТ
2. Пионеры дизайна1
3. НЛО
4. темах жизнеобеспечения сейчас являются сравнительно недорогим дополнением к компьютеру которое легко окуп
5. Тема- ~~Информационные характеристики и перспективы развития твердотельной флэшпамяти~
6. Партизанское движение на Украине в годы ВОВ.html
7. 22 стоматологія А в т о р е ф е р а т дисертації на здобуття наукового ступе
8. Реферат Вплив загальної керованої гіпертермії на стан імунної системи у хворих на інфекційний ендокардит
9. минус средние издержки в т
10. Реферат- Методы бухгалтерского учета
11. Уголовно-процессуальное право
12. Контрольная работа- Изменение средней рентабельности
13. Острый живот. Неотложные состояния в гинекологии.html
14. Признаки и категории преступлений
15. Контрольная работа- Проект разработки стратегического плана предприятия с помощью Microsoft Project
16. Проблемы и пути развития фондового рынка в Российской Федерации
17. тема знаний о спбах и средствах изменения состя обьекта осущх в определенном процессе
18. реферат дисертації на здобуття наукового ступеня кандидата ветеринарних наук
19.  ~ вежливость королей
20. темами. В качестве конкретной сложной системы выбран вуз основной целью управления которым является обеспеч.