ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ v КАФЕДРА С А П Р
И Г О Ш И Н А Л. В. Методические указания к выполнению лаборат...
27 downloads
169 Views
566KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ v КАФЕДРА С А П Р
И Г О Ш И Н А Л. В. Методические указания к выполнению лабораторных и индивидуальных работ по курсу "Алгоритмические языки и программирование" Часть 1
Пенза 1999
Содержание 1. Алфавит языка Паскаль 2. Данные в языке Паскаль 2.1 Порядковые типы данных 2.1.1 Целые типы данных 2.1.2 Логический тип данных 2.1.3 Символьный тип данных 2.1.4 Перечислимый тип данных 2.1.5 Ограниченный тип данных 2.2 Вещественные типы данных 3. Структура программы на языке Паскаль 3.1 Описание меток 3.2 Описание переменных 3.3 Описание типов 3.4 Описание простых и типизированных констант 4. Арифметические выражения 5. Логические выражения 6. Составной оператор 7. Оператор присваивания 8. Процедуры ввода и вывода данных Лабораторная работа № 1 9. Операторы условной и безусловной передачи управления Лабораторная работа № 2 10. Оператор варианта 11. Операторы циклов 11.1 Оператор цикла с предусловием 11.2 Оператор цикла с постусловием 11.3 Оператор цикла с параметром Лабораторная работа № 3 Лабораторная работа № 4 12. Массивы и их описание 12.1 Работа с одномерными массивами Лабораторная работа № 5 12.2 Работа с двумерными массивами Лабораторная работа № 6 13. Строковый тип данных. Операции над строками 14. Множества в Паскале, их описание. Операции над множествами 15. Тип данных - записи, их описание и использование. Оператор присоединения 15.1 Работа с массивом из записей Лабораторная работа № 7 16. Подпрограммы
16.1
Процедуры. Описание процедур. Область действия имён Локальные и глобальные параметры Лабораторная работа №8 16.2 Подпрограммы типа FUNCTION, их описание Лабораторная работа №9 17. Задача сортировки: алгоритмы и программы 17.1 Сортировка выбором 17.2 Обменная сортировка 17.3 Сортировка слиянием Лабораторная работа №10 18. Задача поиска: алгоритмы и программы 18.1 Линейный поиск 18.2 Двоичный поиск Лабораторная работа №11
1. Алфавит языка Паскаль Алгоритмический язык Pascal (Паскаль) был разработан Никлаусом Виртом в 1969-71гг. Современный вариант - язык Turbo Pascal - расширение американского стандарта ANSI Pascal. Система Turbo Pascal (TP) является интегрированной средой, включающей: - универсальный текстовый редактор; - компилятор входного языка; - редактор связей; - встроенный символический отладчик. Текст программы на языке ТР представляет собой последовательность строк, состоящих из символов, образующих алфавит языка. Строки программы завершаются специальными управляющими символами, не входящими в алфавит (CR - возврат каретки - клавиша Enter и LF - новая линия). Максимальная длина строки составляет 126 символов. 1.
В алфавит языка входят: Буквы латинского алфавита от a до z и от A до Z, а также знак подчеркивания "_", который приравнивается к буквам. (В ТР нет различия между прописными и строчными буквами алфавита, кроме случаев, когда они входят в символьные и строковые выражения).
2.
Арабские цифры от 0 до 9.
3.
Специальные символы, их 23: + - * / = . , : ; ' < > ( ) { } [ ] $ @ # ^ и пробел.
Символы из языка используются для построения базовых элементов лексем. В ТР определены следующие классы лексем: 1) Служебные (ключевые или зарезервированные) слова: Begin, End, Var, Type, Label, Const, If, Then, Else, For, Do, While, Repeat и другие. Служебные слова нельзя использовать не по назначению. Они не могут использоваться в качестве идентификаторов. 2) Имена (или идентификаторы) вводятся программистом для обозначения (в программе) переменных, констант, типов, меток, процедур, функций, объектов, моделей, полей в записях и т.п. Они формируются только из букв и цифр, причем первой должна быть буква. Длина имени может быть произвольной, но компилятор воспринимает только первые 63 символа. Идентификаторы вводятся в программу посредством описаний.
3) Изображения - группа лексем, обозначающих числа, символьные строки и некоторые другие значения. 4) Знаки операций, которые формируются из одного или нескольких специальных символов или служебных слов: а) арифметические операции: + (сложение), - (вычитание), * (умножение), / (деление вещественных чисел), mod (деление целых чисел), div (остаток от деления двух целых чисел); б) операции отношения: < - (меньше), > - (больше), = - (не меньше), = - (равно), - (не равно); в) логические операции: and - логическое И, or - логическое ИЛИ, not логическое НЕ, xor - исключительное ИЛИ; г) операции над множествами: * - пересечение множеств, + - объединение множеств, - - вычитание множеств, IN - принадлежность множеству. 5) Разделители, которые формируются из специальных символов. 6) Комментарии - произвольная последовательность символов, в том числе и русских букв, заключенных в фигурные скобки {…} или (* … *), предназначенная для пояснений в программе. Комментарии могут находиться между любыми двумя лексемами программы. 7) Пробел, не имеющий графического изображения, используется для отделения лексем друг от друга.
2. Данные в языке Паскаль В языке Паскаль любая переменная характеризуется своим типом. Под типом, в данном случае, понимается множество значений, которые может принимать переменная, а также множество операций, допустимых над данной переменной. Тип определяет формат внутреннего представления данных в памяти компьютера. Тип переменной определяется при ее описании, и он не может быть изменен в процессе выполнения программы. Переменная может участвовать только в операциях, допустимых ее типом. Паскаль имеет развитую систему типов. Классификация типов данных, приведенная на рисунке 1, взята из книги [1] и не является единственной. В языке предусмотрен механизм создания новых типов данных на основе базовых. Поэтому общее число типов, используемых в программе, может быть сколь угодно большим.
Рассмотрим сначала так называемые простые или базовые типы, являющиеся основой для построения других типов. Их иногда называют также стандартными типами данных. Типы
Простые
Структурированные
Порядковые
Целые
Вещественные
Логический
Массивы
Символьный
Ссылочный
Записи
Перечислимый
Строковый
Множества
Ограниченный
Процедурный
Файлы
Объекты Рисунок 1 2.1 Порядковые типы данных Порядковые типы характеризуются тем, что каждый из них имеет конечное число возможных значений и с каждым из них можно сопоставить некоторое целое число - порядковый номер значения. К порядковым типам относятся: - целый тип; - логический (или булевой) тип; - символьный тип; - перечислимый (или перечисляемый) тип; - ограниченный (или интервальный) тип, который также называют тип-диапазон. К любому из них применима стандартная функция ORD(Х), результатом которой является порядковый номер значения Х. К порядковым типам можно также применять функции: PRED(X) - возвращает предыдущее значение порядкового типа; SUCC(X) - возвращает следующее значение порядкового типа. 2.1.1 Целые типы данных
Эта группа типов обозначает множество целых чисел в различных диапазонах. Диапазон возможных значений целых типов зависит от их внутреннего представления, которое может занимать один, два или четыре байта. В таблице 1 приведены имена (или названия) всех возможных целых типов (их всего 5), а также длина их внутреннего представления в байтах и диапазоны возможных значений каждого из типов. Таблица 1 Целые типы Название
Длина, байт
Byte ShortInt Word Integer LongInt
1 1 2 2 4
Диапазон значений 0…255 -128…+127 0…65535 -32768…+32767 -2147483648…+2147483647
Значения целых типов могут изображаться в программе двумя способами: в десятичном виде (в виде последовательности цифр от 0 до 9) и в шестнадцатеричном виде (в виде последовательности цифр от 0 до 9 и букв от A до F, перед которыми ставится знак $). Над целыми значениями допустимы следующие арифметические операции: + - сложение, - - вычитание, * - умножение, / - деление и две дополнительные операции "типа деление", а именно, Div - деление нацело, с отбрасыванием дробной части и Mod - взятие остатка от целочисленного деления. При применении к целым значениям всех этих операций, кроме / деления получается результат целого типа, а деление (/) всегда дает вещественный результат. К значениям целых типов могут быть применены стандартные процедуры и функции, некоторые из них приведены в таблицах 2 и 3. При действиях с целочисленными значениями тип результата будет соответствовать типу операндов, а если операнды относятся к различным целым типам, - типу того операнда, который имеет максимальный диапазон значений. Возможное переполнение результата никак не контролируется, что может привести к непредсказуемым результатам.
Таблица 2
Стандартные функции, применимые к целым типам Обращение Hi(X) Lo(X) Odd(X) Swap(X)
Тип аргумента Integer Word Integer Word LongInt Integer Word
Тип результата Byte Byte Byte Byte Boolean Integer Word
Действие Возвращает старший байт аргумента Возвращает младший байт аргумента Возвращает значение True, если Х - нечетное Меняет местами байты в слове
Таблица 3 Стандартные процедуры, применимые к целым типам Описание процедуры Randomize
Тип параметров
Inc(X) Dec(X) Inc(X,N) Dec(X,N)
X - целое X - целое Dec(X,N) Dec(X,N)
Без параметров
Назначение Гарантирует несовпадение последовательностей случайных чисел, выдаваемых функцией Random Увеличивает значение Х на 1 Уменьшает значение Х на 1 Увеличивает значение Х на N Уменьшает значение Х на N
2.1.2 Логический тип данных Логический тип (Boolean) состоит из 2-х значений: False (Ложь) и True (Истина). Над значениями этого типа допустимы операции сравнения, причем False < True. Для них справедливы правила: ORD(False) = True; ORD(True) = False; SUCC(False) = True; PRED(True) = False. Значения логического типа занимают 1 байт. С логическим типом связаны логические операции: AND (И), OR (ИЛИ), NOT (НЕ). 2.1.3 Символьный тип данных
являются символы из Значениями символьного типа (Char) множества ASCII (American Code for Information Interchange - Американский стандартный код для обмена информацией). Это множество состоит из 256 различных символов, упорядоченных определенным образом. Оно содержит символы строчных и прописных букв, цифр и других символов, включая специальные управляющие символы. Каждому символу приписывается целое число в диапазоне от 0 до 255. Это число служит кодом внутреннего представления символа, его возвращает функция ORD. Если символьное значение имеет графическое изображение, то оно изображается в программе соответствующим знаком, заключенным в апострофы (одинарные кавычки): 'A', 'B', …, 'a', 'b', …, '1', '2', …, '*', '+' и т. д. Если символ не имеет графического изображения, то используют другую форму записи: #K, где К - целочисленный код символа. Например: #13 - Enter; #27 - Esc; #8 - Backspace. Так как символы упорядочены, то к типу Char применимы операции сравнения, например: 'A' < 'M'; 'A' < 'a' и т. п., а также стандартные функции: CHR(b) - преобразует выражение b типа byte в символ и возвращает его своим значением. Например: Chr(90) возвращает в качестве результата символ 'Z'. ORD(S) - возвращает в качестве результата код символа S в таблице символов ASCII. Например: Ord('Z') возвращает код, равный 90. UPCASE(CH) - возвращает прописную латинскую букву, если CH строчная латинская буква, в противном случае возвращает сам символ CH. Например: Upcase('z') возвращает символ 'Z'. PRED(S) - возвращает символ, предшествующий символу S. SUCC(S) - возвращает символ, следующий за символом S. 2.1.4 Перечислимый тип данных Перечислимый (или перечисляемый) тип данных задается списком значений (объектов), которые могут принимать переменные этого типа. При этом каждый объект имеет имя. Соответствие между значениями перечисляемого типа и порядковыми номерами этих значений устанавливается порядком перечисления: первое значение в списке получает порядковый номер 0, второе - 1 и т.д. Максимальное число объектов в перечисляемом типе равно 65366 значений. К значениям перечислимого типа применимы стандартные функции Ord, Pred, Succ, а также операции отношений. Переменные этого типа повышают наглядность программы и позволяют автоматически контролировать допустимость значений переменных. Рассмотрим примеры порядковых типов.
1. Описание дней недели: TypeDays=(Monday,Tuesday,Wednsday,Thday,Friday,Sutterday,Sunday). 2. Описание месяцев года: TypeYear=(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec). 2.1.5 Ограниченный тип данных На основе четырех рассмотренных порядковых типов можно определить новые, порядковые типы: например, можно сузить диапазон значений любого из 4-х порядковых типов. Такие типы называют ограниченными (или интервальными) типами. Другое их название диапазоны. Такие типы задаются границами своих значений внутри базового типа: .. Примеры определения типов - диапазонов: Typedate=1..31; TypeMonth=1..12; TypeSim='A'..'Z' Можно сразу определить переменную типа - диапазон: Day:1..31; Month:1..12; Sim:'A'..'Z' и т.п. Необходимо помнить, что левая граница диапазона не должна превышать правой. К значениям этого типа могут быть применены стандартные функции: HIGH(X) - возвращает максимальное значение типа - диапазона, к которому принадлежит переменная Х; LOW(X) - возвращает минимальное значение типа - диапазона, к которому принадлежит переменная Х. 2.2 Вещественные типы данных Эта группа типов представляет множества значений в различных диапазонах. ТР поддерживает пять различных вещественных типа (табл. 4). Таблица 4 Название Real Single Double Extended Comp
Длина, байт Число цифр мантиссы 6 4 8 10 8
11-12 7-8 15-16 19-20 0
Диапазон значений 2.9 E-39…1.7 E +38 1.5 E-45…3.4 E+38 5.0 E-324…1.7 E+308 3.4E-4951…1.1E+4932 -2 E+63… +2 E+63 -1
Все вещественные типы, кроме Real, используются если в ПК есть арифметический сопроцессор.
Данные вещественного типа могут быть представлены в двух видах: с фиксированной точкой и с плавающей точкой. Значения с фиксированной точкой изображаются десятичным числом с дробной частью, которой может быть нулевой, например: 0.5, 5.25, 5.0, -16. 055 и т.п. Значения с плавающей точкой изображаются следующим образом: m E p, где m - мантисса вещественного числа, Е - признак порядка (число 10), р - порядок числа; m - целое или вещественное число с фиксированной точкой, положительное или отрицательное; р - только целое, положительное или отрицательное, например: 22 −5 4 -1.6 Е 22 (−1.6 ⋅ 10 ) . 4 Е -5 ( 4 ⋅ 10 ), 0.62 Е 4 ( 0.62 ⋅ 10 ), Над значениями вещественных типов допустимы четыре арифметических операции: *, /, +, -. Целые и вещественные числа именуются как "число без знака". В таблице 5 приведены некоторые стандартные математические функции и функции преобразования типов, которые используются при работе с целыми и вещественными значениями. Таблица 5 Вызов Функции
Тип аргумента
Abs(X)
Тип результата
Целый Вещественный Sin(X) Вещественный Cos(X) Вещественный ArcTan(X) Вещественный Sqrt(X) Целый Вещественный Sqr(X) Целый Вещественный Exp(X) Вещественный Ln(X) Вещественный
Целый Вещественный Вещественный Вещественный Вещественный Вещественный Вещественный Целый Вещественный Вещественный Вещественный
Pi Trunc(X) Frac(X) Int(X) Round(X)
Нет аргумента Вещественный Вещественный Вещественный Вещественный
Вещественный Longint Вещественный Вещественный Longint
Random
Нет аргумента Вещественный
Назначение функции Вычисление абсолютного значения Х Синус Х радиан Косинус Х радиан Арктангенс Х радиан Квадратный корень из Х, (Х>0) Значение Х, возведенное в квадрат Значение е в степени Х Натуральный логарифм Х, (Х>0) Значение числа π Целая часть числа Х Дробная часть числа Х Целая часть числа Х Округление Х до ближайшего целого Случайное число из диапазона (0...1)
Random(X) Word
Word
Odd(X)
Логический
Целый
Случайное число из диапазона (0...Х) Возвращает значение True, если Х - нечетное
Замечания к таблице 5: 1. Под целым типом понимается один из типов языка (Byte, ShortInt, Word, Integer, LongInt); 2. Под вещественным типом понимается тип Real или иной тип с плавающей точкой. Математические функции очень чувствительны к диапазону своих аргументов. Кроме того, возвращаемые значения целых типов должны в них умещаться, иначе возможны фатальные последствия. 3. Функция ArcTan(X) возвращает главное значение арктангенса (в диапазоне от - π /2 до + π/2). 4. Функции Trunc и Int отличаются только типом возвращаемого значения.
3. Структура программ на языке TurboPascal Любая программа на языке TurboPascal(ТР) состоит из двух основных разделов: раздела описаний данных и раздела операторов, и заканчивается всегда символом «.».
Раздел описаний Begin Раздел операторов End. Раздел описаний может включать в себя подразделы описания меток, констант, типов, переменных, а также подпрограмм, реализуемых в виде процедур или функций. Если в программе используются стандартные или библиотечные модули (Unit), то первой должна стоять директива Uses, в которой перечисляются используемые модули. Рекомендуется всегда включать в программу директиву: Uses CRT; Она подсоединяет стандартный модуль CRT, содержащий описание процедур, функций, констант, типов и переменных, позволяющих работать с цветом, звуком, экраном и ускорить операции ввода-вывода данных. Кроме двух основных разделов в программу можно и нужно включать комментарии: пояснения к программе, данные о разработчиках и т.п. Раздел описаний может содержать следующие подразделы:
1. Список имен, используемых модулей. 2. Объявление меток. 3. Объявление констант. 4. Объявление типов. 5. Объявление переменных. 6. Описание процедур и функций. Не все подразделы обязательны. Каждый из подразделов раздела описаний начинается своим ключевым словом. Список имен модулей начинается с ключевого слова USES. Раздел меток начинается с ключевого слова LABEL , раздел констант CONST , раздел типов - TYPE , раздел переменных - VAR . Раздел операторов следует за разделом описаний и всегда заключается в операторные скобки, определяемые ключевыми словами Begin ... End. Операторы отделяются друг от друга символом ";". Запись операторов в строке может начинаться с любой позиции. В одной строке можно записать несколько операторов. Один оператор может быть записан в нескольких строках. 3.1 Описание меток Метка представляет собой правильный идентификатор или любое целое без знака от 1 до 9999. Метки должны быть описаны в подразделе Label. Каждая метка описывается только один раз в каждой программной единице (основной программе или подпрограммах). Label метка; или Label метка1, метка2, …, меткаN; В программе метка ставится перед оператором, на который передается управление и отделяется от него символом ":". Метка : выполняемый оператор; Примеры описания меток: Label m1, m2, met1, l1, lab, 125; 3.2 Описание переменных Любая переменная, используемая в программе (и подпрограммах) должна быть определена (описана) в подразделе Var раздела описаний, причем каждая переменная описывается только один раз в каждой программной единице. Определение переменной должно содержать имя переменной и ее тип, разделенные двоеточием. VAR имя переменной : тип; Примеры:
Var x:real; i: byte; S: char; b: boolean; Days: 1..31; Переменные одного типа записываются друг за другом через запятые: Var a, b, c : real; I,j,k:byte; m, months:1..12; Для переменных, описанных в каждой программной единице, отводится определенный объем памяти. Переменные, описанные в основной (главной) программе, называют глобальными переменными. Общий объем памяти, отведенный под глобальные переменные, не должен превышать 64 Кбайта. Переменные, описываемые в подпрограммах, называются локальными переменными. 3.3 Описание типов В простейших случаях тип переменных указывается явно, при их описании в разделе Var: Var Имя переменной: тип; Можно сопоставить типу некоторое имя и описать его в разделе Type: Type Имя типа = Тип; Например: Type Diapason = 1..1000; T_days = 1..31; T_symbol = 'a'..'z'; T_Month = (j,f,mr,ap,may,jn,jl,ag,s,o,n,d); Это дает возможность программисту определять и использовать свои собственные типы, а не стандартные. Далее можно имена типов, введенные в подразделе Type, использовать в подразделе Var: Var i, n :Diapason; Day: T_days; Sim, ch: T_symbol; Mes: T_Month; 3.4 Описание простых и типизированных констант
Простые константы могут быть заданы явно своим значением (0.5, 0, 100, 3.14, 'A', -5 и т.п.) или обозначены именем и в этом случае константы должны быть описаны в подразделе Const: Const Имя константы = Значение; Например: Const N=200; A=0.5; sym='*'; В качестве значений константы могут быть использованы целые и вещественные числа, строки символов, идентификаторы других констант, константные выражения. Например: Const Max=100; Min=10; S=(Max+Min) div 2; Кроме простых констант используют так называемые типизированные константы или переменные со стартовым значением. Они занимают промежуточное положение между простыми константами и переменными, что отражается в следующих их свойствах: 1. Типизированные константы описываются в подразделе Const своим именем. 2. Они, как и константы, получают свое начальное значение. 3. Аналогично переменным, они имеют тип, который задается при их описании. 4. Они могут, как переменные, получать новые значения, в процессе работы программы. Таким образом, название "константа" достаточно условное. Типипзированные константы можно использовать как обычные переменные, но им присваиваются начальные значения. Описание типизированных констант: Const Имя типизированной константы: Тип = Типизированная константа; В свою очередь, понятие типизированной константы может включать одно из: Обычная константа Константа ссылочного типа Идентификатор программы Изображение массива Изображение множества Изображение записи Изображение объекта Примеры: Const
Max:integer=999; Min:real=-0.01; Index:1..1000=1; Примеры более сложных типизированных констант (массивов, множеств, записей) будут приведены при описании соответствующих типов. Замечание: простые константы могут использоваться в описании других констант или типов, а типизированные нет!
4. Арифметические выражения Арифметические выражения строятся из арифметических констант, переменных, функций и операций над ними. Все данные, входящие в арифметические выражения, должны быть одного типа, хотя иногда допускается использовать в одном выражении данные целого и вещественного типов. При построении арифметических выражений следует учитывать следующие правила: 1. Выражение записывается в строчку. Например, выражение:
2⋅ a ⋅ x + 3⋅b ⋅ y − 4 ⋅ x 2 .5 ⋅ ( a + b + c )
на Паскале будет записываться следующим образом: (2*a*x+3*b*y-4*x)/(2.5*(a+b+c)) 2. Скобки в арифметических выражениях только круглые. Число открывающихся скобок должно равняться числу закрывающихся скобок. 3. Нельзя записывать два знака операций подряд, без скобок, например в выражении:
3⋅ a + b следует записать: (3*a+b)/(-x). −x
4. Порядок выполнения арифметических операций соответствии со старшинством операций: 1) значения функций; 2) *, /, div, mod; 3) +, -. Рассмотрим порядок вычисления на примере:
слева
направо
(a ⋅ Sinx + b ⋅ Cosy ) 2 x (a 2 + b 2 ) ⋅ Sin( ) y Представленное выражение будет вычисляться в седующем порядке: 1) Вычисление функции Sin(x); 2) a*Sin(x); 3) Cos(y); 4) b*cos(y); 5) aSin(x)+b*Cos(y); 6) SQR(aSin(x)+b*Cos(y)) - получено значение в числителе; 7) Вычисление x/y; 8) Sin(x/y); 8) a*a; 9) b*b; 10) SQR(a*a+b*b); 11) SQR(a*a+b*b)*Sin(x/y) - получено значение в знаменателе;
в
12) числитель/знаменатель - получен результат.
5. Логические выражения Логические выражения строятся из логических (булевых) данных, логических операций (OR, AND, NOT) и операций отношений. В операциях отношений могут участвовать арифметические и логические выражения, а также символьные данные. Результатом логического выражения является значение True или False. Приоритет операций в логических выражениях следующий: 1) NOT 2) * , /, Div, Mod, AND 3) +, -, OR 4) =, =, . Внутри каждой группы приоритет равный. В логических выражениях допускается использование только круглых скобок. Сначала выполняются действия в скобках, начиная с самых внутренних. В круглые скобки обязательно заключаются части выражения, стоящие слева и справа от логических операций AND и OR. Примеры логических выражений: A 0 ⎫ Y =⎨ ⎬ 2 ⋅ + ≤ , 0 a x b x ⎩ ⎭ Условный оператор будет иметь вид: If x>0 Then Y:=a*x+b Else Y:=a*x*x+b; Кроме передачи управления, в зависимости от некоторого условия, порядок выполнения операторов можно изменить с помощью оператора безусловной передачи управления вида: GOTO метка; Действие оператора Goto состоит в передаче управления в программе соотвествующему помеченному оператору. При использовании меток необходимо помнить: - метка, на которую ссылается оператор Goto, должна быть описана в подразделе Label и она обязательно должна встретиться в теле программы; - метка может ставиться перед ключевым словом End, что означает переход на конец текущего блока Begin … End; - следует избегать переходов (и расстановки меток), передающих управление внутрь операторов циклов; зато выход из циклов с помощью Goto может быть использован для их досрочного завершения;
- область действия оператора goto и связанных с ним меток строго локализована. Метки, описанные в основной части программы, действуют только в ней. Метки, описанные в подпрограммах, определенных программистом, действуют только внутри этих подпрограмм и поэтому передача управления извне подпрограммы на метку внутри нее невозможна. Кроме того, ТР обладает средствами безусловного выхода из программных блоков (процедур, функций или основной программы), что позволяет завершать программу или подпрограммы без предварительных переходов по меткам. Для этого используются системные процедуры EXIT и HALT. Вызов Exit вызывает завершение работы только того программного блока, в котором он используется. Процедура Halt завершает выполнение всей программы. Лабораторная работа №2 Алгоритмы и программы с разветвлением Цель работы: 1. Построение схемы разветвляющегося алгоритма; 2. Изучение структур разветвления (условных операторов) ТР. Типовой пример Составить схему алгоритма и программу для вычисления значений функции F для заданных значений переменной x и постоянных a, b. F = a tgx +√ |x-2| , при x < 2; F = (a2 - b2) Cos π , при x = 2; F = (x-2)3 Sin πx/2 , при x > 2.
(1) (2) (3)
Примечание: При составлении алгоритма и программы не забывайте анализировать знаменатель (он не должен равняться нулю), учитывайте область определения математических функций, значения подкоренных выражений и типы данных, участвующих в выражениях. В рассматриваемом примере значение подкоренного выражения всегда больше 0, арифметические функции Sinх и Cosх определены для любых значений х.
При вычислении значений функции tgx необходимо использовать выражение tgx = sinx /cosx. В связи с этим нужно анализировать значение, которое может принимать знаменатель: cosx не должен равняться 0. Все данные вещественного типа. Схема алгоритма
Начало
x>2
Ввод х
Cos(x) =0
х
нет Вычисление F по форм. (1)
x2 then F:= (x-2)*(х-2)*(х-2)* Sin(Pi *х/2); if x=2 then F:= (a*a-b*b)* Cos (Pi); if x2 then F:= (x-2)*(х-2)*(х-2)* Sin(Pi/2*x) else if x=2 then F:= (a*a-b*b)* Cos (Pi) else if Cos(x) 0 then F:= a* Sin(x)/Cos(x)+ Sqrt(Abs(x-2)) else begin Writeln(' Знаменатель равен 0'); exit { Выход из программы } end; {Вывод результатов} Writeln(' При x= ',x:6:2,' F= ',F:8:3); readln; End. Варианты самостоятельных заданий
F = Sin x +
x − 5 ,
при
x < 5
1. F = a 2 ⋅ Cos π + ln ( x + a ), F = ( x − 5 ) 3 ⋅ tg
x , 2
F = ctg x + a ⋅
x + 2,
при x = 5 , a − const
при x > 5
при x < − 2
2 2 2. F = ( a − b ) ⋅ cos π , при x = − 2 , a , b − const π ⋅x 3
F = ( x − 2 ) ⋅ sin
F = Arctg x +
,
2
x + 3,
при x < 0
3. F = ( a − b ) + cos π x , F = x 3 ⋅ ctg
π ⋅x 2
при x > − 2
при x = 0 , a , b − const
при x > 0
,
F = tg ( x − a ) + | x + 4 |, 2 2 4. F = ( a − b ) + cos π , F = ( x − 2 ) 3 ⋅ sin π ⋅ x ,
F = a ⋅ tg x + ln x − 2 ,
при x < 2
при x = 2 , a , b − const при x > 2 F = arctg x +
при x < 2
x − 2,
при x < 2
5. F = ( x 2 − b 2 ), при x = 2, a , b − const 6. F = (5 − b 2 ) + cos π ⋅ x, при x = 2, b − const F = ( x − 2 ) ⋅ sin
π ⋅x 2
,
F = ln( x − 2) ⋅ sin
при x > 2
7.
x , 2
при x > 2
8.
F = a ⋅ x + tg x + ln | x − 5 |,
при x < 5
F = tg x + 1+ | x − 2 |,
F = ( x 2 − b 2 ) + cos π ,
при x < 0
при x = 5, b − const F = ( a 2 + x ) + cos π , при x = 0, a − const F = ( x − 2) ⋅ sin 2π ⋅ x, при x > 5 F = x 3 ⋅ sin π ⋅ x, при x > 0 F = a ⋅ x + ctg x +
ln | x − 3 |,
при x < 3
2 2 9. F = ( x − b ) + cos π ⋅ x , при x = 3 , b − const F = ( x − b ) ⋅ sin 2 π ⋅ x , при x > 3
F = tg x + 1+ | x |,
при x < 0
10. F = ( a 2 + 2 x ) + sin π , при x = 0, a − const F = 3 x + sin π ⋅ x , при x > 0
F = Sin x +
x + 5,
при
x > −5
11. F = x ⋅ Cos π + ln ( x + b ), 2
x , 2
F = ( x − 5 ) 3 ⋅ tg
F = tg x + a ⋅ x ⋅
x = − 5 , b − const
x < −5
при
x + 2,
при
при x < − 2
12. F = ( a 2 − x 2 ) ⋅ cos x ⋅ π , при x = − 2 , a − const F = ( x − 2 ) ⋅ sin
π ⋅x 2
,
при x > − 2
F = Arctg x + x + 3 , при x > − 3 13. F = ( a − b ) + Cos x , при x = − 3 , b − const π ⋅x F = x 3 ⋅ tg , при x < − 3 2
F = tg ( x − 4) + | x + 4 |,
при x < 4
F = x ⋅ tg x + ln x − 2 ,
при x < 2
2 2 2 14. F = (a − x ) + cosπ , при x = 4, a − const 15. F = ( x + b) ⋅ x, при x = 2, b − const π ⋅x F = ( x − 4)3 ⋅ sin π ⋅ x, при x > 4 F = ( x − 2) ⋅ sin , при x > 2
2
F = arctg x +
2⋅ x − 2,
при x < 2
2 16. F = ( 4 − x ) + cos π ⋅ x ,
F = ln( x − 2 ) ⋅ sin
x , 2
F = ctg x + 1+ | x − 2 |,
при x < 5
при x = 2 17. F = ( x 2 − 52 ) + sin π ⋅ x, при x = 5 F = ( x − 2) ⋅ cos 2π ⋅ x, при x > 5 при x > 2
при x < 0
18. F = (a + x) + sin π , при x = 0, a − const F = a ⋅ x ⋅ cos π ⋅ x, при x > 0 F = 2 ⋅ x + tg x + ln | x − 3 |, при x < 3 2 2 19. F = ( x − 3) − sin 2 ⋅ x, при x = 3 F = ( x + 3) − cosπ ⋅ x, при x > 3
F = ctg x + 3+ | x |,
F = a ⋅ x + tg x + ln | x − 5 |,
при x < 0
2 20. F = (a ⋅ x + 1) + sin π , при x = 0, a − const F = (3 − x) ⋅ sin π ⋅ x, при x > 0
10. Оператор выбора Для разветвления в программе более чем в 2-х направлениях, можно использовать оператор выбора: Case OF End Или Case OF Else End Ключ выбора - выражение любого порядкового типа; - одна или более конструкций вида: : ; - выражение того же типа, что и ключ выбора; Оператор выбора работает следующим образом: вычисляется значение выражения , а затем в последовательности операторов отыскивается такой, которому предшествует константа, равная вычисленному значению. Найденный оператор выполняется, после чего оператор выбора завершает работу. Если в списке выбора нет такой константы, то управление передается оператору, стоящему за ключеваым словом Else. Часть Else может отсутствовать и в этом случае оператор выбора завершает свою работу. 11. Операторы циклов В языке ТР имеются три различных оператора, с помощью которых организуются циклические (повторяющиеся) фрагменты программ. 11.1 Оператор цикла с предусловием Оператор цикла с предусловием имеет вид: While Do ; где - логическое выражение. Если логическое выражение принимает значение TRUE (истина), то выполняется оператор, стоящий после ключевого слова Do, в противном случае оператор While прекращает свою работу. На месте одного оператора может располагаться группа операторов, заключённых в операторные скобки (Begin ... end). 11.2 Оператор цикла с постусловием Оператор цикла с постусловием имеет вид: Repeat Until где - последовательность операторов ТР;
- логическое выражение. Операторы "тела цикла" выполняются хотя бы один раз, после чего вычисляется значение логического выражения и если это значение FALSE, то операторы "тела цикла" повторяются, в противном случае оператор цикла завершает свою работу. 11.3 Оператор цикла с параметром Оператор цикла с параметром имеет вид: For := To < конеч.знач.> Do ; где - переменная любого порядкового типа; - начальное значение - выражение того же типа; - конечное значение - выражение того же типа; На месте одного оператора может располагаться группа операторов, заключённых в операторные скобки (Begin ... end). Для более гибкого управления операторами циклов For, While, Repeat в ТР введены две процедуры: BREAK - реализует немедленный выход из цикла; действие процедуры заключается в передаче управления оператору, стоящему сразу за после последнего оператора цикла. CONTINUE - обеспечивает досрочное завершение очередного прохода цикла, что эквивалентно передаче управления в самый конец циклического оператора. Лабораторная работа №3 Циклические алгоритмы и программы Цель работы: 1. Построение схем циклических алгоритмов; 2. Использование операторов циклов (повторений): Типовой пример Составить схему алгоритма и программу для вычисления значений функции Y для значений переменной х, изменяющейся в интервале от a до b с заданным шагом h.
Y = 3 (6 x 2 − x 3 ) Решение Так как в языке Pascal нет стандартной функции извлечения корня любой степени кроме квадратного, для вычисления функции Y воспользуемся переходом к функциям Exp и Ln.
Y = 3 (6 x 2 − x 3 ) = Exp (1.0 / 3.0 * Ln(6 x 2 − x 3 )). При программировании необходимо учесть, что выражение, стоящее под знаком Ln, может быть только положительным: (6x2-x3) > 0.
Исходными данными в этой задаче являются значения a,b и h. Начальное значение х принимаем равным а (х:=а). Каждое следующее значение х вычисляется по формуле х:=х+h. Вычисления функции Y для новых значений х заканчиваются, когда значение х становится больше, чем заданное значение b. Схема алгоритма и программа вычислений зависит от того, какой оператор цикла используется в программе. Рассмотрим три различных варианта решения поставленной задачи. Вариант 1 Схема алгоритма с использованием цикла While ... Do
6x2-x3 >0
Начало
нет
да Ввод a, b, h
Вычисление F
x := a
Вывод F
Вывод сообщения А Конец
А Пока x≤b
x := x+h
Текст программы {Лабораторная работа 3} {Программирование циклов с использованием оператора WHILE} {Студенты гр. ..... Фамилии …} Uses crt; {Подключение стандартного модуля TP} Var x,y,H,A,B: real; BEGIN Clrscr; { Очистка экрана} Writeln(' Введите A B H'); read(A,B,H); x:=A; While xb да
Конец Текст программы {Лабораторная работа 3} {Программирование циклов с использованием конструкции REPEAT…UNTIL} {Студенты гр. ... Фамилии ...} Uses crt; {Подключение стандартного модуля TP} Var x,y,A,B,H: real; BEGIN Clrscr; { Очистка экрана} Writeln(' Введите A B H'); readln(A,B,H); x:=A; Repeat if (6*x*x-x*x*x)=0
Вывод сообщения
нет
да n=(b-a)/h+1
Вычисление F
x := x+h
A x := a
Вывод F
Конец
Текст программы {Лабораторная работа 3} {Программирование циклов с использованием оператора FOR}
{Студенты гр. ....} Uses crt; Var x,y,A,B,H:real; n,i: integer; BEGIN Clrscr; Writeln(' Введите A B H'); read(A,B,H); n:= Round((B-A)/H)+1; x:=A; For i:=1 To n Do begin if (6*x*x-x*x*x)=ε
Вычисление а по ф-ле (2)
нет
Вывод S
Конец
S:=S+a
да продолжение цикла Текст программы {Лабораторная работа 4} {Вычисление суммы членов ряда с использованием оператора WHILE} {Студенты гр. ..... Фамилии…} Uses crt; {Подключение стандартного модуля TP} Var x,a,eps,S: real; n:integer; BEGIN Clrscr; { Очистка экрана} Writeln(' Введите x,eps'); read(x,eps);
{ Задание начальных значений переменных} a:=x; n:=1; S:=a; While а>=eps Do Begin n:=n+1; {Вычисление очередного члена ряда по формуле (2)} a:=a*x*(2*n+1)/((2*n-1)*(n+1)); s:=s+a; end; Writeln(' Cумма членов ряда S = ',S:10:4,' Число итераций n = ',n:5); END. Рекомендация: При составлении программы не забывайте анализировать знаменатель (он не должен равняться нулю) и типы данных участвующих в выражениях. Варианты самостоятельных заданий 1. an = (2n-1)*x / 2n; 2. an = x /((3n-2)(3n+1)); 3. an = 10n / xn!; 4. an = xn! /(2n)!; 5. an = x* 2n / n!; 6. an = x ( 3n * n!) / (3n)!; 7. an = 3nx / (n+2)!; 8. an = (2n-1) * x / 2n; 9. an = nx / 3(n+1)/2; 10. an = (x+1) * 5n / n!;
11. an = x/n2; 12. an = 2nx / (n+1)!; 13. an = 3nx * 3n / n!; 14. an = x(n+1) / (n+2)!; 15. an = nx / 2(n+1); 16. an = 2xn! / (2n)!; 17. an = xn! / (3n)!; 18. an = x * 5n / (n+5)!; 19. an = x * 2n /(2n+1)!; 20. an = x(2n+1)(2n-1)/(2n+1)!;
12 Массивы и их описание Массивы относятся к структурированным типам данных в ТР. Массив состоит из фиксированного числа элементов (компонент) одного типа и характеризуется общим именем. Доступ к отдельным элементам массива осуществляется с помощью общего имени и порядкового номера (индекса или адреса) необходимого элемента. Имя массива - это любое допустимое в ТР имя, отличное от служебных слов, имен функций и процедур. Массив может быть описан в подразделе Var или в подразделах Var и Type, одновременно.
Первая форма описания - в подразделе Var: Var Имя_массива: Array [T1] OF [T2]; где Array (Массив) и Of (Из) - служебные слова. T1 - список типов индексов (в качестве индексов чаще всего используются переменные типа - диапазон, но возможно использование перечислимого типа); Т2 - тип элементов массива (любой тип ТР как простой, так и структурированный). Например: 1) Var Mas: Array[1..10] of integer; - описание массива, состоящего из 10 целых чисел и имеющего имя Mas; 2) Var S: array[1..20] of real; - описание массива, состоящего из 20 вещественных чисел и имеющего имя S; 3) Var Matr:array[1..20,1..20] of byte; - описание массива (матрицы размером 20 на 20), содержащего 400 элементов типа byte. Если массив объявлен, то к любому его элементу можно обратиться с помощью его имени и индексов. Например: 1) Mas[5]:=21; - пятому элементу массива Mas присвоено значение, равное 21. 2) For i:=1 to 20 do S[i]:=0.0; - присвоение всем 20 элементам массива S значения, равного 0.0 (обнуление массива). 3) For i:=1 to 20 do For j:=1 to 20 do Matr[i,j]:=random(100); заполнение массива (матрицы) на 400 чисел случайными числами из диапазона от 0 до 100. Вторая форма описания - в подразделах Var и Type: Type Имя_типа_массива = Array [T1] OF [T2]; Var Имя_массива: Имя_типа_массива; Например: 1) Type Tm=array[1..100] of byte; - описание нового типа для массива, состоящего из 100 чисел типа byte Var Mas:Tm; - описание массива с именем Mas. 2) Type Typ_Mas = array[1..100] of char; Var M:Typ_Mas; - описание массива содержащего 100 символов. 3) Type Tmatr = Array[1..25,1..10] of real; Var Matr1,Matr2:Tmatr; - описание матриц с именами Matr1 и Matr2. Массив с одним индексом называют одномерным, с двумя - двумерным, с тремя - трехмерным и т.д. Число индексов у массива в ТР не ограничивается, но необходимо помнить, что размер массива не должен превышать 64 Кбайт. Любой двумерный массив представляет собой матрицу: первому индексу можно поставить в соответствие строки, а второму - столбцы
матрицы. Кроме того, двумерный массив можно интерпретировать как одномерный, элементами которого является другой одномерный массив. Описание такого массива имеет вид: Type tstr=array[1..25] of real; Var masssiv:array[1..10] of tstr; - это описание равносильно описанию в примере 3, приведенному выше для массивов с именами Matr1 и Matr2. Оперативная память под элементы массива выделяется на этапе трансляции. В памяти компьютера элементы массива следуют друг за другом. Если массив двумерный, то память под него выделяется так, что быстрее меняется самый правый индекс. В качестве примера рассмотрим порядок выделения оперативной памяти под массив, описанный следующим образом: Var M:array[1..2,1..4] of byte; Этот массив будет располагаться в памяти в следующем порядке: M[1,1]; M[1,2]; M[1,3]; M[1,4]; M[2,1]; M[2,2]; M[2,3]; M[2,4]. В ТР можно одним оператором присваивания передать все элементы одного массива другому массиву того же типа. Например: Var m1,m2:array[1..10] of word; ... Begin . . . m1:=m2; { перезапись из одного массива в другой} ... End. Для сравнения содержимого двух массивов необходимо использовать оператор цикла с параметром и указываться индексы. Типизированные константы - массивы В качестве начального значения используется список констант, отделенных друг от друга запятыми. Список заключается в круглые скобки. Примеры: 1) Const Mas:array[1..10] of byte=(1,1,1,1,1,1,1,1,1,1); - заполнение массива из 10 целых чисел значением, равным единице. 2) Const massim: array[0..5] of char = ('a','b','c','d','e','f'); - заполнение массива из 6 элементов символами - буквами латинского алфавита. 3) Const Matr: array[1..5,1..2]of byte = ((0,0),(0,0),(0,0),(0,0),(0,0)); обнуление матрицы из 10 целых чисел. Замечание: количество переменных в списке констант должно строго соответствовать объявленной длине массива по каждому индексу! Лабораторная работа №5
12.1 Работа с одномерными массивами Цель работы: 1. Построение схем алгоритмов с использованием массивов; 3. Разработка программ с использованием одномерных массивов Типовой пример Составить схему алгоритма и программу определения суммы S всех положительных элементов одномерного массива M, содержащего К вещественных чисел (К≤20). Числа в массив M ввести с экрана дисплея, результат суммирования (S) также вывести на экран. Схема алгоритма
S := 0.0
Начало
Ввод К
Цикл i:=1,K
Цикл i :=1,K
нет
Вывод S
Конец
M[i]>0 да
Ввод в М[i]
S:=S + M[i]
Текст программы {Лабораторная работа 5} {Работа с одномерными массивами Студенты гр. Фамилии …} Uses crt; {Подключение стандартного модуля TP} Var m:array[1..20] of real; {Описание массива вещественных чисел}
S:real; {описание переменной для хранения суммы} i,K:byte; {описание переменных для счетчика и количества чисел} Begin Clrscr; {Очистка экрана} Write(' Введите число элементов в массиве К ='); Readln(K); Writeln(' Введите ',K,' вещественных чисел через пробел'); For i:=1 to K do read(M[i]); { Ввод вещественных чисел} writeln; { Переход на новую строку на экране} S:=0.0; { Присвоение начального значения суммы} For i:=1 to K do If M[i]>0 then S:=S+M[i]; { Суммирование положительных чисел} Writeln(' S = ',S); { Вывод полученной суммы} End. Варианты самостоятельных заданий 1. Составить схему алгоритма и программу определения суммы наибольшего и наименьшего элементов вещественного массива А={ai}, i=1,N, N- число элементов массива (N33 или нажать Ctrl/z и Enter. При n>33 возникает переполнение при умножение чисел с плавающей запятой. Рекурсивный вызов может быть также косвенным. В этом случае подпрограмма обращается к себе опосредованно, путем вызова другой подпрограммы, в которой, в свою очередь, содержится обращение к первой. Такой вызов иногда называют закольцованным. Для реализации такой возможности в ТР используется опережающее описание процедур и функций и директива Forward. Для этого в самом начале программы вставляют только заголовки процедуры или функции в виде: Procedure имя-процедуры(параметры);Forward; или Function имя_функции(параметры);Forward; Позже, в необходимых местах, описываются сами процедуры или функции в обычном виде и в их заголовке параметры уже указывать не нужно.
Например: процедура с именем А вызывает процедуру с именем В, а процедура В, в свою очередь, вызывает процедуру А. Procedure A(y:тип);Forward; {Опережающее описание процедуры А} Procedure B(x:тип); { Заголовок процедуры В} . . . {Раздел описаний процедуры В} begin ... A(p); {Вызов процедуры А из В} ... end; Procedure A; {Основное описание процедуры А} ... {Раздел описаний процедуры А} Begin ... B(g); {Вызов процедуры В из А} ... End; Лабораторная работа №9 Цель работы: Преобрести навыки разработки программ использованием функций, представленных в теоретической части.
с
Типовое задание Составить программу, максимально используя заданных выражений, подпрограммы типа FUNCTION.
для
Варианты заданий t
m
yj
n F x a = ( + ) +∑ m ∑ i 1. c i =1
j =1
2.
F=
( a + b) n m
∑ ((a + b)
m
j =1
n
m
yk n F x a = + + ∑ ∑ i 3. аc m i =1
k =1
4.
F=
(a m − b n ) m
∑ ((a − b)
m
j =1
t
5. F =
∑ (x − c ) i =1 t +2
с
k
t
i
⋅ (t − 2)!
6. F =
− yj)
∑ (x i =1
i
− c) k
c!−(k − c)!
− yj)
вычисления
s
7.
(n + m)!
F = (a n + b m ) +
p
t
∑ zk − ∑ s j k =1
F=
8.
j =1
∑ (x i =1 n
∑ (a k =1
n
9.
F=
a −b k
k
∑ (x
i
i =1
11.
F=
t
t
+ b)
+ ∑ ( yi + a )
∑ (a i =1
F=
i
i =1
k
xi − b)
n
k
+ ∑ (b yi − a )
i =1
− bk ) n − n!
− yi ) n − (n + 3)!
F=
12.
− bk ) n − n!
k
a k + bt
m
t
+ ∑ yi
k
∑x i =1
i =1
i
a⋅ yj F x y ( ) = + + ∑ ∑ i i m 14. i =1 j =1 c
yj
m
13. F = ∑ ( xi − c) + ∑ c m n
k
∑ (a
t
i =1
− y i ) s + s!
n
k =1
a k + 2 + b t −2 t
10.
i =1
∑ (x
i
j =1
n
n
k
t
15.
m
F = ∑ ( xi + a ⋅ t )t + ∑ i =1 n
j =1
c⋅ yj m
m
n
yk F = x + + n! ∑ ∑ i m n 17. i =1 k =1 а + c k
19. F =
∑ (c − x ) i =1 k
20.
F=
k
i
i =1
c!−k! m
yk = ( + ) + F x a ∑ ∑ i 18. аm n
i =1
k
i
с ⋅ (c!−k!)
16. F =
(a + c ) t
∑ (c + x )
a k + bt k
∑ (x i =1
i
− b)
k =1
t
+ ∑ yi i =1
Примечание: При разработке программ не забывайте анализировать область допустимых значений функций.
17. Задача сортировки: алгоритмы и программы Сортировка данных при решении задач на ЭВМ занимает значительную часть времени. В настоящее время разработано большое число алгоритмов сортировки (упорядочения), отличающихся друг от друга различными признаками: сложностью алгоритма, временем решения, затратами памяти ЭВМ, числом сортируемых элементов, до какой степени элементы уже отсортированы, где располагаются сортируемые данные: во внешней памяти
(например, на диске) или в оперативной памяти. Очевидно, что с отсортированными данными работать легче, чем с произвольно расположенными данными. Когда элементы отсортированы, их проще найти или определить, что их нет среди данных. Наиболее простыми алгоритмами сортировки считаются алгоритмы, известные в литературе под названиями - обменная (или пузырьковая) сортировка и сортировка выбором. Эти алгоритмы, в худшем случае, решают задачу сортировки за время пропорциональное N2, где N - число сортируемых элементов. Такие алгоритмы называют алгоритмами с квадратичной сложностью. Эти алгоритмы используют, когда число сортируемых элементов относительно не велико (до 1000). Для сортировки данных больших объемов используют более сложные, с точки зрения реализации, алгоритмы. Сложность этих алгоритмов определяется по формулам: N*lnN или N*log2N. Такие алгоритмы называют алгоритмами с логарифмической сложностью или быстрой сортировки. Эти алгоритмы используют чаще всего при сортировке данных в оперативной памяти, например в массивах или в динамических списках. Для сортировки данных во внешней памяти можно использовать алгоритм сортировки слиянием. Кроме перечисленных алгоритмов существует большое число других алгоритмов, с которыми можно ознакомиться, например, в [2,3]. 17.1 Сортировка выбором В литературе описано несколько различных модификаций сортировки выбором, но суть их всех заключается в том, что на очередном шаге выбирается необходимый элемент, и он помещается на заданное место в сортируемой последовательности. Рассмотрим одну их модификаций сортировки выбором. Пусть дан одномерный неупорядоченный массив, содержащий целые числа М={mi}, i=1,n; n - число элементов. Необходимо упорядочить элементы этого массива по возрастанию их значений. На первом шаге из элементов массива выбирается минимальный, и он меняется местами с элементом, стоящем на первом месте. На втором шаге из оставшихся неупорядоченных элементов, начиная со второго, выбирается следующий минимальный элемент, и он меняется местами с элементом, стоящем на втором месте. Процесс повторяется до тех пор, пока не будут переставлены все элементы. Последний элемент можно не проверять, так как к этому времени все элементы уже будут стоять на своих местах. В том случае, если требуется упорядочить элементы по убыванию их значений, осуществляется поиск и перемещение максимального элемента. Рассмотрим работу алгоритма по схеме.
Схема алгоритма сортировки выбором
Начало Ввод n и M[i], i=1,n
Обмен M[i_min]:= M[i]
Цикл i=1,n-1
M[i]:=Min
Min:=M[i] i_min:=i
нет
Цикл j=i+1,n
Вывод нового M
M[j]< Min
Конец да
Min:=M[j] i_min:=j
Min - минимальный элемент i_min - адрес минимального элемента Текст программы сортировки выбором
Uses crt; Var M:array[1..1000] of integer; n, i, j, Min, i_min:integer; Begin Clrscr;
Write(' Введите длину массива n = '); Readln(n); { Вместо ввода с клавиатуры заполним массив случайными числами из диапазона от 0 до 500} For i:=1 to n do M[i]:=Random(500); For i:=1 to n-1 do Begin {принимаем за минимум i-й элемент} Min:=M[i]; i_min:=i; For j:=i+1 to n do If M[j]<Min then Begin {найдено меньшее число - запоминаем его и его адрес} Min:=M[j]; i_min:=j; End; {Обмен} M[i_min]:=M[i]; M[i]:=Min; End; Writeln(' Упорядоченный массив'); For i:=1 to n do write(M[i],' '); readkey; End.
17.2 Обменная сортировка Обменная сортировка основывается на последовательном сравнении двух рядом стоящих элементов и если порядок следования нарушен, элементы меняются местами. Сравнения производятся до тех пор, пока при очередном цикле просмотра всех рядом стоящих пар элементов, ни одна пара элементов не менялась местами. В том случае, если элементы массива уже упорядочены, алгоритм закончит свою работу после одного цикла просмотра всех рядом стоящих пар. Просмор пар может начинаться с начала массива или с его конца, в последнем случае алгоритм называют алгоритмом пузырьковой сортировки. Подробнее об этом можно ознакомиться в [2,3]. Рассмотрим работу алгоритма по схеме. Схема алгоритма обменной сортировки
Начало
Обмен Z= M[i] M[i]=M[i+1]
Ввод данных
M[i+1]=Z Key=1
А Key=0
Key=0
нет
да А Цикл i=1,n-1
нет
M[i]> M[i+1]
Вывод нового М
да
Конец
Key - ключ, определяющий была ли перестановка пар элементов; Z - переменная, необходимая для хранения промежуточного элемента при перестановке. Текст программы обменной сортировки Uses crt; Var M:array[1..1000] of integer; i,Z,n:integer; Key:byte; Begin Clrscr; {Ввод n и формирование массива М как в предыдущей программе} Repeat
Key:=0; For i:=1 to n-1 do If M[i] > M[i+1] then begin Z:=M[i]; M[i]:=M[i+1]; M[i+1]:=Z; Key:=1; end; Until Key=0; Writeln(' Упорядоченный массив'); For i:=1 to n do write(M[i],' '); readkey; End. 17.3 Сортировка слиянием Алгоритм сортировки слиянием используется в тех случаях, когда данные расположены на внешних носителях информации или сортируется данные очень большого объема, которые невозможно расположить в оперативной памяти целиком. В этом случае данные могут быть сохранены, например, в отдельных файлах, таких размеров, которые могут быть помещены в оперативную память, например в массивы. Производится загрузка данных из файлов в массивы и сортировка данных каждого из массивов отдельно. Упорядоченные данные снова записываются в файлы. Затем производится сортировка слиянием уже упорядоченных данных, расположенных в отдельных файлах. Поскольку мы пока не знакомы с работой с файлами в ТР, рассмотрим алгоритм сортировки слиянием на примере слияния двух предварительно упорядоченных массивов Х и Y в один массив Z. Данные в массивах расположены в порядке возрастания их значений. Обзначим через переменные dx, dy - длину (размер) массивов X, Y соответственно. Переменные ix, iy - счетчики (адреса) тех же массивов. Переменная iz - счетчик числа элементов нового массива Z. Схема алгоритма сортировки слиянием Начало Ввод dx, dy, X, Y
ix:=1; iy:=1; iz:=0;
X[ix]≤ Y[iy]
нет да
iz:=iz+1; Z[iz]:=X[ix]; ix:=ix+1; да
iz:=iz+1; Z[iz]:=Y[iy]; iy:=iy+1; да
iy≤dy
ix≤dx нет
нет
Цикл i:=iy,dy
Цикл i:=ix,dx
iz:=iz+1; Z[iz]:=Y[i]
iz:=iz+1; Z[iz]:=X[i]
Вывод Конец Z[i],i:= 1,iz Текст программы сортировки слиянием Uses crt; Var { Описание массивов и переменных} X, Y: array[1..1000] of integer; Z: array[1..2000] of integer; dx,dy,ix,iy,iz,i:integer; Begin Clrscr; { Ввод данных} Write(' Введите длину массива Х '); readln(dx);
Writeln(' Введите упорядоченный по возрастанию массив Х'); For i:=1 to dx do read(X[i]); readln; Write(' Введите длину массива Y '); readln(dy); Writeln(' Введите упорядоченный по возрастанию массив Y'); For i:=1 to dy do read(Y[i]); readln; ix:=1; iy:=1; iz:=0; While (ixisk then break; writeln(' Заданного элемента нет'); readln; End. 18.2 Двоичный поиск Двоичный поиск заключается в следующем: вычисляется середина массива и элемент xi, находящийся по найденному адресу, сравнивается с искомым. Если элементы xi и isk равны, то поиск закончен. Если xi < isk, то искомый элемент может находиться в последующей xi части массива, в противном случае поиск надо осуществлять в предшествующей xi части массива. Такой подход позволяет сократить число просматриваемых элементов в 2 раза. Далее в выделенной части массива также определяется средний элемент, и он сравнивается с искомым. Подобная процедура повторяется до тех пор, пока ни будет найден заданный элемент или пока не совпадут начальный и конечный адрес просматриваемой, на очередном шаге, части массива. Если эти адреса совпадут и к этому моменту элемент не найден, то его в массиве нет. Временная сложность алгоритма двоичного поиска ∼ log2n. Схема алгоритма двоичного поиска Начало
Ввод данных n,X,isk
First:=1 Last:=n
First - адрес начала просматриваемой части. Last - адрес конца просматриваемой части
Цикл Last ≥ First Элемент не найден
adr:=(First+ Last) div 2
Last:=adr-1
First:=adr+1
Вывод элемента
Текст программы Uses crt; Var X:array[1..10000] of integer; isk,i,n,adr,First,Last:integer; Begin write(' Введите число элементов в массиве - n '); readln(n);
write(' Введите элементы массива Х '); for i:=1 to n do read(X[i]); writeln; write(' Введите искомое число'); readln(isk); First:=1; Last:=n; while First