Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмические языки высокого уровня. Курс лекций

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
940 Кб
Скачать

Сортировка методом прямого включения

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

Сортировка методом прямого включения, как и все описанные выше, производится по шагам. На k-м шаге считается, что часть массива, содержащая первые k – 1 элементов, уже упорядочена, т.е.

а[1] < = a [2]< = … < = a[k-1].

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

j (1 < = j < = k-1), что a[j] < = a[k]<a[j+1].

Затем надо вставить элемент a[k] на найденное место.

С каждым шагом отсортированная часть массива увеличивается. Для выполнения полной сортировки потребуется выполнить n-1 шаг.

Пример программы

Описание: сортировка методом прямого включения.

Program sorting3; var

n,x,j,k:integer;

a: array [1..50] of integer;

begin

writeln('введите размер массива'); readln(n);

for j:=1 to n do read(a[j]); for k:=2 to n do

begin x:=a[k]; j:=k-1;

while (j>0) and (x<=a[j]) do begin

a[j+1]:=a[j]; dec(j); {j:=j-1}

end;

a[j+1]:=x;

end;

writeln;

for j:=1 to n do write(a[j]:5);

end.

71

4.2.2. Записи

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

Описание записи в языке Pascal осуществляется с помощью слу- жебного слова record, вслед за которым описываются компоненты записи. Завершается описание записи служебным словом end.

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

type

TRec = Record FIO: String[20]; TEL: String[7] end;

var

rec: TRec;

Описание записей возможно и без использования имени типа, на- пример:

var

rec: Record

FIO: String[20]; TEL: String[7] end;

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

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

72

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

with rec do оператор;

rec – имя записи, оператор оператор, простой или со- ставной.

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

with rec do begin

FIO:='Иванов А.А.'; TEL:='2223322'; end;

Такая алгоритмическая конструкция полностью идентична сле- дующей:

rec.FIO:='Иванов А.А.'; rec.TEL:='2223322';

Инициализация записей может производиться с помощью типизи- рованных констант:

type

RecType = Record x,y: Word;

ch: Char;

dim: Array[1..3] of Byte end;

const

Rec: RecType = ( x: 127; y: 255;

ch: 'A';

dim: (2, 4, 8) );

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

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

type

TFigure = record

73

type_of_figure: string[10]; color_of_figure: byte;

...

case integer of

1:(x1,y1,x2,y2: integer);

2:(a1,a2,b1,b2,c1,c2: integer);

3:(x,y: integer; radius: word);

end;

var figure: TFigure;

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

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

4.2.3. Множества

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

Множественный тип описывается с помощью служебных слов

Set of:

type M = Set of B; М множественный тип, В базо- вый тип.

Описание переменной множественного типа:

type

M = Set of 'A'..'D'; var

MS: M;

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

var C: Set of 0..7;

74

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

['A', 'C'] [0, 2, 7] [3, 7, 11..14]

Константа вида [ ] означает пустое подмножество. Количество ба- зовых элементов не должно превышать 256. Инициализация величин множественного типа может производиться с помощью типизиро- ванных констант:

const seLit: Set of 'A'..'D'= [];

Порядок перечисления элементов базового типа в константах без- различен.

Значение переменной множественного типа может быть задано конструкцией вида [T], где T – переменная базового типа.

Допустима конструкция: type T = set of char; Множество включает в себя набор элементов базового типа, все

подмножества данного множества, а также пустое подмножество. Так, переменная Т множественного типа var T: Set of 1..3; может принимать восемь различных значений:

[ ] [1] [2] [3] [1,2] [1,3] [2,3] [1,2,3]

К переменным и константам множественного типа применимы операции присваивания (:=), объединения (+), пересечения (*) и вы- читания (-):

['A','B'] + ['A','D'] даст ['A','B','D']; ['A','D'] * ['A','B','C'] даст ['A']; ['A','B','C'] - ['A','B'] даст ['C'].

Результат выполнения этих операций есть величина множествен- ного типа.

К множественным величинам применимы операции: тождествен- ность (=), нетождественность (<>), содержится в (<=), содержит (>=).

Результат выполнения этих операций имеет логический тип:

['A','B'] = ['A','C'] даст FALSE;

['A','B'] <> ['A','C'] даст TRUE; ['B'] <= ['B','C'] даст TRUE; ['C','D'] >= ['A'] даст FALSE.

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

75

сти элемента множеству часто используется вместо операций отно- шения, например:

'A' in ['A', 'B'] даст TRUE, 2 in [1, 3, 6] даст FALSE.

Пример программы

Описание: в программе реализован знаменитый метод Шерлока Холмса метод исключений (Детективная история Шерлока Холмса).

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

actress – актриса; colonel – полковник; countess – графиня; baronet – баронет; drwatson – д-р Ватсон; maid – служанка; minister – ми-

нистр; mp – моя персона; moriarty – Мориарти; narrator – рассказ-

чик; sheepdog – овчарка; stranger – иностранец; suspects – подозре-

ваемые; murder – убийца; body – тело; roоm – комната.

Program detectiv; uses crt;

type persons=(actress,colonel, countess, baronet, drwatson, maid, minister, mp, moriarty, narrator, sheepdog, stranger); {имена участников событий}

setpersons=set of persons; {структура информационной модели участников событий}

const

sppersons: array [persons] of string=({actress-}('актриса'), {colonel-}('полковник'),{countess -}('графиня'),{baronet-} ('баронет'),{drwatson-} ('Ватсон'),

{maid -} ('служанка'),{minister -} ('министр'), {mp -} ('Холмс'),{moriarty -}('Мориарти'),

{narrator -} ('рассказчик'),{sheepdog -} ('овчарка'),{stranger -} ('иностранец')); var

suspects{подозреваемые}, tempted{заинтересованные в смер- ти},

able {возможные участники}, away {имеющие железное алиби}, good {люди высоких нравственных и моральных качеств} :

setpersons;

murderer,body:persons; {убийца и убитый} location: string; {место убийства} {процедура ввода значения перечисляемого типа имени участ-

ника событий. Процедура вводит со стандартного устройства ввода строку символов с именем и формирует выходной параметр перечисляемого типа persons}

procedure readpersons(var name:persons); var s:string;

i:persons; begin

readln(s);

76

for i:=actress to stranger do if sppersons[i]=s then begin name:=i;

exit {выход из блока, т.е. из процедуры} end;

writeln('Ошибка ввода!!!');

HALT {прекращение выполнения программы} end;

{процедура вывода значения перечисляемого типа persons} procedure writepersons(name:persons);

begin write(sppersons[name])

end;

{процедура ввода значений в множество типа setpersons со стандартного устройства ввода, при вводе одно значение от другого отделяется пробелом}

procedure readset(var mn:setpersons); label 1;

var s{строка с введенными значениями}, r{cтрока с одним значением}:string; i,name:persons;{текущее и введенное значения}

j,beg,fin:integer;{для фиксации позиций в строке ввода} begin

mn:=[];

{чтение строки символов со значениями} readln(s);

if length(s)=0 then exit;{строка пустая выход} {разбор строки по элементам}

beg:=1;

for j:=1 to length(s) do begin

if (s[j]=' ')or(j=length(s)) then begin

if s[j]=' ' then fin:=j else fin:=length(s)+1; if fin>beg+1 then begin r:=copy(s,beg,fin-beg);

for i:=actress to stranger do if sppersons[i]=r then begin name:=i;

goto 1 end;

writeln('Ошибка ввода!!!');

Halt;

1: mn:=mn+[name]; beg:=fin+1;

end

else beg:=fin+1 {подавление пробелов} end;

end;

end{readset};

{процедура вывода значений множества типа setpersons на стандартное устройство вывода}

77

procedure writeset(mn:setpersons);

var i:persons;{текущее значение для вывода} k:integer;{количество значений, выведенных в одну строку}

begin k:=0;

for i:=actress to stranger do if i in mn then begin write(sppersons[i]+' '); k:=k+1;

if k=6 then begin writeln;

k:=0; end end;

if k<>0 then writeln end;

{функция определения мощности множества типа setpersons} function card(mn:setpersons):integer;

var i:persons;{имя элемента множества} k:integer;{счетчик числа элементов множества} begin

k:=0;

for i:=actress to stranger do if i in mn then k:=k+1; card:=k;

end; begin

clrscr;

{процесс исключения } {нет ни одного человека вне подозрений}

suspects:=[actress..stranger]; writeln ; writeln;

writeln('Итак, Вы поставлены в тупик, не правда ли?'); writeln('Ну, Вы знаете методы, давайте используем их.'); writeln('Во-первых, скажите мне, кто убит'); writeln('Возможный ответ:');

writeset(suspects);

readpersons(body); if body=drwatson then

writeln('Подлое дело! Вы мне симпатичны.'); {самоубийство не предполагается} suspects:=suspects-[body];

write ('Теперь назовите мне всех,');

writeln(' кто был заинтересован в смерти - '); write('убит(а) '); writepersons(body); writeln('.'); writeln('Возможный ответ:');

writeset(suspects);

readset(tempted);

writeln('Где произошло преступление?'); readln(location);

78

writeln('Итак,'+location+'. Кто мог в это время здесь нахо- диться ?');

writeln('Возможный ответ:'); writeset(suspects); readset(able);

writeln('У кого железное алиби'); writeln('Возможный ответ:'); writeset(suspects); readset(away);

write ('КТО не мог совершить убийство'); writeln(' из нравственных принципов?'); writeln('Возможный ответ:'); writeset(suspects);

readset(good);

{вычисление подозреваемых} suspects:=suspects*tempted*able-away-good;

if suspects=[] then writeln('Я боюсь указать кандидата.') else if card(suspects)=1 then begin {вывод убийцы} murderer:=actress;

while not(murderer in suspects)and(murderer<stranger) do murderer:=succ(murderer);

write('Убийца - '); writepersons(murderer); writeln; end

else begin

for murderer:=actress to stranger do

if murderer in suspects then write(sppersons[murderer], ' ');

writeln end; end.

4.2.4. Файлы

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

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

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

79

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

'LAB1.DAT'

'c:\ABC150\pr.txt' 'my_files'

Типы файлов. Pascal поддерживает три типа файлов: текстовые файлы, типизированные файлы, нетипизированные файлы (файлы прямого доступа).

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

Описание: file of тип типизированный файл; text текстовый файл;

file нетипизированный файл.

var

f1: file of char; {типизированный файл симво- лов}

f2: file of integer; {типизированный файл це- лых чисел}

f3: file; {нетипизированный файл} t: text; {текстовый файл}

Стандартные процедуры и функции при работе с файлами

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

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

Reset(f) открывает для чтения файл, с которым связана файловая переменная f. После успешного выполнения процедуры Reset файл готов к чтению из него первого элемента. Процедура

80

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