Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_Паскал.doc
Скачиваний:
2
Добавлен:
21.09.2019
Размер:
1.21 Mб
Скачать

Множинний тип

Множинні типи належать до трохи незвичного і порівняно рідко використовуваного засобу мови Pascal. Однак у ряді випадків використання множинних типів дозволяє помітно підвищити компактність і наочність програм.

Значення множинного типу, так само, як масиви, будуються з декількох значень одного (базового) типу. Однак, на відміну від масивів і записів, значення множинного типу може містити будь-яку кількість РІЗНИХ елементів базового типу - від нуля елементів (порожня множина) до всіх можливих значень базового типу. Іншими словами, можливими значеннями змінних множинного типу є ВСІ ПІДМНОЖИНИ значень базового типу.

Множинний тип задається за допомогою двох службових слів - set і of - і наступного за ним базового типу. Наприклад:

type

Digits = set of 1..5;

var

S : Digits;

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

<порожня>

1, 2

1, 2, 3

1, 5

1, 3, 4, 5

3, 4, 5

1, 2, 3, 4, 5

Потрібно звернути увагу на дві обставини. По-перше, усі значення базового типу, що утворять конкретні значення множинного типу, повинні бути РІЗНІ. По-друге, порядок "розташування" елементів у множині ніяк НЕ ФІКСУЄТЬСЯ. Це відповідає прийнятому в математиці трактуванню множинм як безповторної неупорядкованої сукупності об'єктів.

Важливим є питання, з яких значень можна будувати множини, чи іншими словами, який може бути базовий тип множини. Авторська версія мови обмежується дискретними типами, однак практично всі реалізації сильно звужують це обмеження. Так, Turbo Pascal допускає як базові типи для множини дискретні типи не більш ніж з 256 різними значеннями, причому (для цілих типів) ці значення повинні лежати в діапазоні від 0 до 255. Таким обмеженням задовольняють тільки стандартні типи byte і char, перераховані типи, а також обмежені типи, утворені з них.

Приведемо ще один приклад опису множини:

type

ElemColor= (Red,Yellow,Blue);

Color= set of ElemColor;

var MyColor: Color;

Сукупність припустимих значень змінної MyColor містить наступні множини:

<nорожня множина>

Red

Yellow

Blue

Red, Yellow

Red, Blue

Yellow, Blue

Red, Yellow, Blue

У Pascal-програмі допускаються явні зображення значень множинних типів, подібно зображенням цілих чи дійсних чисел. Зображення множини (чи конструктор множини) будується зі списку елементів множини, розділених комами. Весь список обмежують квадратними дужками, наприклад:

[1,2,5] [Red,Yellow]

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

Крім того, можна вказувати діапазони значень, що складаються з пари граничних значень, розділених знаком '. .' (дві крапки); наприклад, два зображення множин [1..3,5] і [1,2,3,5] еквівалентні.

Порожня множина зображується двома квадратними дужками: [ ].

Необхідно пам'ятати, що множина - це безповторна сукупність елементів, так що, наприклад, три наступні зображення позначають одну і туж множину:

[1,2,3]

[1,1,2,3]

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

Приведемо ще кілька прикладів описів і зображень множин:

type

SetOfChar= set of char,-

Digits= set of 0..100; var

MyChars : SetOfChar;

MyDigl,MyDig2 : Digits; begin

MyChars:= ['а'..'z','0'..'9','-'];

MyDigl:= [];

MyDig2:=MyDigl;

MyDigl:=[x..x+10,0,y-l,y+l];

Корисність того чи іншого типу даних визначається, у першу чергу, набором припустимих операцій над значеннями цих типів. Що стосується множинних типів, то тут маються наступні групи операцій:

  • теоретико-множинне об'єднання, перетинання і віднімання множин;

  • перевірка належності елемента множині;

  • перевірка на рівність і нерівність множин;

  • перевірка на входження (належність) однієї множини в іншій.

Розглянемо докладніше перераховані операції.

  1. Об'єднання, перетинання і віднімання множин. Ці операції позначаються, відповідно, символами ’+’, ’*’ і ’-' і означають традиційні дії з множинами прийняті в математиці. Якщо представити дві множини А и В у виді прямокутників, то множину-результат перерахованих операцій можна наочно зобразити за допомогою зафарбованих частин цих прямокутників:

об'єднання множин — множина, що складається з елементів, що належать множинам А и В.

перетин множин — множина, що складається з елементів, що належать одночасно обом множинам.

віднімання множин — множина, що складається з тих елементів однієї множини, що не належать іншій.

Наступний приклад ілюструє приведені операції (у правому стовпчику показана множина-результат операції):

[1,2] + [3,4] [1,2,3,4]

[1..10] + [5..15] [1..15]

[1. .10] * [5. .15] [5. .10]

[1,2] * [3,4] []

[1..10] - [5..15] [1..4]

  1. Перевірка належності до мнжини. Ця логічна операція позначається службовим словом in. Правий операнд повинний бути множиною, лівий - значенням базового типу множини. Операція видає true, якщо значення входить у множину, і false у противному випадку. Наприклад, наступні вирази:

2 in [1..10,12]

5 in [1,2,7,10]

видають відповідно true і false.

Операцію перевірки належності зручно використовувати для виключення більш складних перевірок. Наприклад, оператор виду

if (ch='а') or (ch='b') or (ch='х') or (ch='у') then S

може бути переписаний у більш компактній і наочній формі:

if ch in ['а','b','х','у'] then S

Помітимо, що другий варіант більш ефективний з погляду швидкодії.

  1. Перевірки на рівність, нерівність і включення безлічей

= рівність (співпадання) двох множин

<> нерівність множин

<= перевірка на входження множини з лівого операнда в множину із правого операнда

>= перевірка на входження множини з правого операнда в множину з лівого операнда

Усі ці операції видають логічне значення true чи falae у залежності від успіху перевірки. Нижче приводяться приклади використання цих операцій.

[1,2,3] = [1,2] false

[1,2,3] >= [1,2] true

[S] <= [1..10] true, якщо 3 – ціле число з діапазону 1. . 10

[1,2,3] <> [1,2,2] true

Необхідно відзначити, що всі операції над множинами працюють досить ефективно, тому має сенс застосовувати їхній усюди, де це необхідно. На жаль, набір операцій над множинами в Раsсаl'е не містить принаймні однієї практично важливої операції - вибірки значення з множини (чи близько зв'язаного з нею засобу циклічного перебору значень множини). Тому при необхідності подібних дій приходиться організовувати цикл по всьому діапазоні значень базового типу, перевіряючи на кожній ітерації належність чергового значення даній множині, наприклад:

var

Symbols : set of char;

S : char; begin

for S:= chr(0) to chr(255) do

if S in Symbols then

<дії з змінною S>

На закінчення приведемо приклад невеликої програми, що використовує поняття множини. Програма реалізує обчислення декількох перших простих чисел методом решета Ератосфена.

program eratosfen;

uses crt;

const n=255;

var nath,kin:set of 2..n ;

next:byte;

j:word;

begin

clrscr;

nath:=[1..n];

kin:=[];

next:=2;

repeat

while not(next in nath)do

inc(next);

kin:=kin+[next];

j:=next;

while j<=n do

begin

nath:=nath-[j];

j:=j+next;

end;

until nath=[];

for j:=2 to n do

if j in kin then write(j:5);

end.