Приклади програмування задач з використанням множини. Складний тип даних – масиви Нагадаємо, що типи даних в мові Паскаль поділяється на прості і складні. До простих типів відносяться стандартні та змінні (перерахований і обмежений); до складних типів – масиви, множини, записи, файли. Елементами складних типів можуть бути прості типи, а також, в свою чергу, складні типи. Введення складних типів робить мову програмування більш потужною і дозволяє складати ефективні програми широкого класу завдань. В математиці, економіці, інформатиці часто використовуються впорядковані набори даних (наприклад, послідовності чисел, таблиці, списки прізвищ). Для їх обробки і вводять поняття масиву. Одновимірні масиви Під масивом розуміємо сукупність кінцевого числа даних одного типу. Масив позначається одним ім’ям. Так, всю сукупність дійсних чисел 1.6, 14.9, -5.0, 8.5, 0.46 – можна вважати масивом і позначати одним ім’ям, наприклад А. Кожен елемент масиву позначається іменем масиву з індексом. Елементи масиву впорядковані за значенням індексу. В математиці, як правило, індекс або вміщується в круглі дужки, або вказується нижче імені масиву, наприклад: А(1), А(2), А(3), А(4), А(5) або А1, А2, А3, А4, А5 або в загальному вигляді Аі, де і = 1, 2, 3, …, n. В мові Паскаль індекс міститься в квадратних дужках. Для розглянутого прикладу елементами масиву А є А[1] = 1.6, А[2] = 14.9, А[3] = -5.0, А[4] = 8.5, А[5] = 0.46. Якщо в програмі використовується масив то він повинен бути описаний або в розділі змінних VAR, або в розділі типів TYPE. Форма опису масиву в розділі змінних VAR має вигляд: VAR _ ім’я масиву: ARRAY[t1] OF _ t2, де ARRAY (масив) і OF (із) – службові слова; t1 – тип індексу, в якості якого може бути будь який простий тип, крім стандартних типів REAL та INTEGER; t2 – тип елементів масиву допустимий на мові Паскаль. Для попереднього прикладу опис масиву має вигляд: VAR А: ARRAY[1..5] OF REAL; де А – ім’я масиву, елементи якого мають базовий тип REAL; тип індексу – обмежений від 1 до 5. Приклади опису масивів: VAR MASSIV: ARRAY[1..N] OF REAL; РІК: ARRAY[СІЧЕНЬ..ГРУДЕНЬ] OF INTEGER; L: ARRAY[РЯДОК] OF BOOLEAN; M1: ARRAY[CHAR] OF КОЛО; Якщо декілька масивів мають однаковий тип індексів і однаковий базовий тип, то допускається в описі об’єднувати масиви у список, наприклад: VAR А, B, C: ARRAY[1..50] OF REAL; Тут оголошено списком три масиви дійсних чисел А, B, C дійсних чисел, кожний з яких містить по 50 елементів (від 1 до 50): А[1], А[2], А[3],…, А[50]; B[1], B[2], B[3],…, B[50]; C[1], C[2], C[3],…, C[50]. Неможна плутати поняття “індекс” і “тип індексу”: тип індексу використовується тільки в розділі опису масиву, а індекс вказується в розділі операторів для позначення конкретних елементів масиву, при цьому індекс повинен бути того ж типу, що й опис типу індексу. У якості індексу може бути вираз, окремим випадком якого є константа або змінна. Елемент масиву інакше називається змінною з індексом. На відміну від неї змінна без індексу називається простою змінною. Елементи масиву можуть стояти як ліворуч оператора присвоювання, так і у виразах. Над елементами масиву можна робити ті операції, які допустимі для даних його базового типу. Якщо базовим типом є INTEGER, то допустимі всі операції над даними цілого типу, включаючи і стандартні функції. Приклади використання елементів масиву в розділі операторів: B[5]:=B[3]+1; SUM:=SUM-C[K]; P1:=A[2*I+1]; Для введення і виведення числових значень масиву використовуються цикли. Наприклад, цикл FOR I:=1 TO 5 DO READ(A[I]); – організує введення п’яти значень елементів масиву А: А[1], А[2], …, А[5], а цикл: FOR I:=1 TO 5 DO WRITE(A[I]); – виведення дев’яти значень елементів того ж масиву. В мові Паскаль крім явного опису масивів у розділі змінних існує друга форма опису, яка складається з двох етапів: спочатку в розділі опису типів TYPE вказується тип масиву, потім у розділі опису змінних VAR перелічуються масиви, які належать до вказаного типу. Введення типа масиву збільшує розділ описів, але у той же час спрощує налагодження програми та утримує від абсурдних помилок, таких, як складання “ЯБЛУК” з “ПРИСКОРЕННЯМ ВІЛЬНОГО ПАДІННЯ”. Зазначення типів у розділі описів допомагає досягнути логічної якості програми і є добрим стилем програмування. Форма запису масиву має вигляд: TYPE _ ім’я типу = ARRAY[t1] OF _ t2; VAR _ ім’я масиву: ім’я типу; Наприклад, в програмі використовується масив А, який складається з 10 елементів дійсного типу. Позначимо тип масиву ім’ям MASSIV. Тоді опис масиву можна виконати наступним чином: TYPE MASSIV=ARRAY[1..10] OF REAL; VAR А: MASSIV; Якщо в цій програмі декілька масивів, наприклад, В, С, D мають той самий тип (тобто тип MASSIV), то зміниться тільки розділ змінних: VAR А,В,С,D: MASSIV; Слід зазначити, що масиви А, В, С, D використовуються в розділі операторів програми. Тип масиву MASSIV введений формально тільки в розділі описів і ніде в програмі не вказується та не оброблюється. Двовимірні масиви До цих пір ми розглядали масиви, кожен елемент яких містив тільки один індекс. Такі масиви зазвичай називають одновимірними. В математиці часто використовуються багатовимірні масиви, тобто масиви масивів. Найширше розповсюдження отримали двовимірні масиви, які інакше називаються матрицями. Наприклад, зображення цілих чисел послідовно в декількох рядках є матрицею: 5 4 3 6 2 8 1 7 4 3 9 5 Дана матриця має розмір 3 на 4, тобто вона складається з трьох рядків і чотирьох стовпців. Якщо усю матрицю позначити одним іменем, наприклад, А, то кожен елемент матриці позначається з двома індексами – А[I,J], де перший індекс I вказує на номер рядка (I = 1, 2, 3), другий індекс J – номер стовпця (J = 1, 2, 3, 4). Таку матрицю можна описати наступним чином (з використанням імені типу, наприклад, М): 1-й варіант опису: TYPE М=ARRAY[1..3, 1..4] OF INTEGER; VAR А: М; – описується кожний тип індексу, потім вказується простий базовий тип елементів масиву INTEGER. 2-й варіант опису: TYPE М=ARRAY[1..3] OF ARRAY[1..4] OF INTEGER; VAR А: М; – спочатку описується тип даних індексу [1..3], потім вказується складний базовий тип ARRAY[1..4] OF INTEGER, який в свою чергу містить опис типу другого індексу і простого базового типу INTEGER. Якщо в програмі необхідно виділити окремі рядки матриці, то зручно ввести такий опис: TYPE М1=ARRAY[1..4] OF INTEGER; М=ARRAY[1..3] OF М1; VAR А: М; В: М1; – тут спочатку описується тип одного рядка М1, а потім через тип рядка М1 – тип всієї матриці М. В розділі змінних вказується, що А є двовимірним масивом, тобто матрицею, а В – одновимірним масивом. 9. Складний тип даних – множини В математиці під множиною розуміється деякий набір елементів. Наприклад, різноманіття фігур на площині (прямокутник, коло, ромб, квадрат і ін.). До множин застосовують наступні операції: – об’єднання (С = АUВ) – кожний елемент множини С є елементом або множини А , або множини В; – перетин (С = А∩В) – кожний елемент множини С є елементом множин А і В одночасно; – різниця двох множин (С = А\В). Кожний елемент множини С є елементом множини А, але не є елементом множини В.  Рис . Операції над множинами: а – об’єднання; б – перетин; в – різниця двох множин. А також перевірка множин на відношення одної до іншої: – збіг (А = В) – кожний елемент множини А є елементом множини В і, навпаки, кожний елемент множини В є елементом множини А; – належність (BЄA або AЭB) – кожний елемент множини B є елементом множини А. Окремим випадком є належність окремого елементу до множини (xЄA).  Рис . Відношення множин: а – А і В збігаються; б – В входить (належить) до А; в – х належить А. Множини в мові Паскаль Під множиною в мові Паскаль розуміють обмежений, невпорядкований набір різноманітних елементів однакового типу. Можна, наприклад, казати про множину радіодеталей, транспортних засобів, приладів тощо. Усій множині в цілому надається ім’я. Тип елементів, які входять до множини, називається базовим. У якості базового типу можна використовувати один з простих типів: стандартний або змінний (перерахований і обмежений). Множини повинні бути оголошені або в розділі змінних VAR, або з використанням розділу типів TYPE. Оголошення множини в розділі змінних має вигляд: VAR _ ім’я множини: SET _ OF _ базовий тип; а з використанням розділу типів: TYPE _ ім’я типу = SET _ OF _ базовий тип; VAR _ ім’я множини: ім’я типу; Наприклад: VAR ПІДСИЛЮВАЧ: SET OF (РЕЗИСТОР, КОНДЕНСАТОР, ТРАНЗИСТОР, ТРАНСФОРМАТОР, ТУМБЛЕР, ДІОД); або, якщо дана множина СХЕМА: TYPE СХЕМА=SET OF (РЕЗИСТОР, КОНДЕНСАТОР, ТРАНЗИСТОР, ТРАНСФОРМАТОР, ТУМБЛЕР, ДІОД); VAR ПІДСИЛЮВАЧ: СХЕМА; або, якщо дана множина СХЕМА, елементами якої є дані типу РАДІОДЕТАЛЬ: TYPE РАДІОДЕТАЛЬ=(РЕЗИСТОР, КОНДЕНСАТОР, ТРАНЗИСТОР, ТРАНСФОРМАТОР, ТУМБЛЕР, ДІОД); СХЕМА=SET OF РАДІОДЕТАЛЬ; VAR ПІДСИЛЮВАЧ: СХЕМА; Значення змінних і констант множини задаються у розділі операторів за допомогою конструктора. Він представляє собою список елементів базового типу, узятий у квадратні дужки. Наприклад: РАДІОДЕТАЛЬ:=[РЕЗИСТОР, КОНДЕНСАТОР, ТРАНЗИСТОР, ТРАНСФОРМАТОР, ТУМБЛЕР, ДІОД]; ФІГУРА:=[КОЛО, РОМБ, КВАДРАТ]; ЛІТЕРА:=[ 'А' , 'В', 'С' ]; ЦИФРА:=[1, 3, 2, 5]; A:=[ ]; {ПОРОЖНЯ МНОЖИНА} В мові Паскаль операції над множинами мають вигляд: Математичний запис | Запис на мові Паскаль | Опис | АUВ | А+В | об’єднання множин A і B | А∩В | А*В | перетин множин A і B | А\В | А-В | різниця множин A і B | А=В | А=В | множини A і B збігаються | А≠В | А<>В | множини A і B не збігаються | BЄA або AЭB | B<=A або A>=B | множина В є підмножиною множини А | xЄA | x_IN_A | значення x належить множині А | ІN – перевірка на належність елемента множині. Приклади програмування задач з використанням множини. Приклад 9.1. Існують три множини символьного типу A, B і C, які задані своїми конструкторами: ['А', 'В', 'D', 'R', 'H']; ['R', 'A', 'H', 'D']; ['А', 'R']. Сформувати нову множину – D = (А∩B)U(A\B), перевірити, чи належить множина С множині D. Програма 9.1. Операції над множинами. PROGRAM P91 (INPUT, OUTPUT); VAR A, B, C, D: SET OF CHAR; {МНОЖИНИ} X: CHAR; {СИМВОЛ} BEGIN A:=['А', 'В', 'D', 'R', 'М']; B:=['R', 'A', 'H', 'D']; C:=['А', 'R']; {РОЗРАХУНОК І ДРУК МНОЖИНИ D} D:=(A*B)+(A-B); WRITE('МНОЖИНА D = '); FOR X:='A' TO 'R' DO ІF X ІN D ТНЕN WRITE(X); WRITELN; {ПЕРЕВІРКА ВКЛЮЧЕННЯ МНОЖИНИ C ДО D} ІF C<=D ТНЕN WRITE('МНОЖИНA C НАЛЕЖИТЬ ДО МНОЖИНИ D') ЕLSE WRITE('МНОЖИНA C НЕ НАЛЕЖИТЬ ДО МНОЖИНИ D') END. ---------------------------------------------------------------------- МНОЖИНА D = ABDMR МНОЖИНA C НАЛЕЖИТЬ ДО МНОЖИНИ D ---------------------------------------------------------------------- Для виведення на екран дисплея елементів нової множини використовується оператор циклу FOR, параметром циклу є символьна змінна X, яка приймає значення кожного символу латинського алфавіту від А до R включно (див. впорядкованість літер латинського алфавіту в додатку). Зверніть увагу на те, що в операторі циклу використовується не весь латинський алфавіт від А до Z, а тільки частина його. Це пов’язано з тим, що задані множини A, B, C не містять символів після літери R, але помилкою не буде, якщо кінцевим значенням параметра циклу взяти символ Z. Приклад 9.2. З множини цілих чисел від 1 до 20 виділити: – множину чисел, що діляться на 6 без залишку; – множину чисел що діляться без залишку або на 2, або на 3. Введемо позначення для наведеної нижче програми 10.2: N – розмірність множини; N2 – множина чисел, що діляться на 2; N3 – множина чисел, що діляться на 3; N6 – множина чисел, що діляться на 6; N23 – множина чисел, що діляться на 2 або 3; К – параметр циклу. Програма 9.2. Знаходження множин кратних чисел. PROGRAM P92 (INPUT, OUTPUT); СОNST N=20; {РОЗМІРНІСТЬ МНОЖИНИ} VAR N2, N3, N6, N23: SET OF INTEGER; К: INTEGER; {ПАРАМЕТР ЦИКЛУ} BEGIN N2:=[ ]; {ПОЧАТКОВЕ ЗНАЧЕННЯ N2} N3:=[ ]; {ПОЧАТКОВЕ ЗНАЧЕННЯ N3} FOR К:=1 TO N DO BEGIN ІF К МОD 2=0 ТНЕN N2:=N2+[К]; ІF К МОD 3=0 ТНЕN N3:=N3+[К] END; N6:=N2*N3; N23:=N2+N3; WRITELN('НА 6 ДІЛЯТЬСЯ ЧИСЛА: '); FOR К:=1 TO N DO ІF К ІN N6 ТНЕN WRITE(К:3); WRITELN; WRITELN('НА 2 АБО НА 3 ДІЛЯТЬСЯ ЧИСЛА: '); FOR К:=1 TO N DO ІF К ІN N23 ТНЕN WRITE(К:3) END. ---------------------------------------------------------------------- НА 6 ДІЛЯТЬСЯ ЧИСЛА: 6 12 18 НА 2 АБО НА 3 ДІЛЯТЬСЯ ЧИСЛА: 2 3 4 6 8 9 10 12 14 15 16 18 20 ---------------------------------------------------------------------- Записи У попередніх розділах розглядались впорядковані (масиви) або невпорядковані (множини) дані однакового типу. Проте в житті найчастіше зустрічаються неоднорідні дані, прикладами можуть бути: календарна дата – номер дня місяця, назва місяця, номер року; відомість складання заліку студентами – прізвище та ініціали студента, оцінка; адреса – назва країни, назва місцевості, назва населеного пункту, назва вулиці тощо, номер будинку, номер приміщення. При цьому з’являється необхідність об’єднувати дані різного типу в одну групу. Для роботи з групою даних в мові Паскаль введено поняття запису. Поняття запису Запис представляє собою сукупність обмеженої кількості даних різного типу. Поняття запису розглянемо на прикладі відомості списку студентів з їх оцінками (табл.1). Таблиця 1 № з/п | Прізвище та ініціали студента | Оцінки (бали) | модуль 1 | модуль 2 | Лаб.роб. | 1. | Андрюхін В.Б. | | | | 2. | Весна В.В. | | | | 3. | Дорошенко К.Ю. | | | | 4. | … | Кожний рядок у цій відомості складається з окремих елементів – даних різного типу: а) номер за порядком – ціле десяткове число; б) прізвище та ініціали студента – масив символів; в) оцінки – масив цілих чисел. Ці дані можна об’єднати в одну групу і вважати записом. Запис в цілому і окремі його елементи позначаються іменами. Позначимо, наприклад, ім’я записів – АВБ, ВВВ, ДКЮ, номер за порядком – Н, прізвище та ініціали – П; оцінки – О. Звернення до елемента запису в програмі виконується за допомогою уточненого (складеного ім’я). Уточнене ім’я містить ім’я запису та ім’я елемента і записується в наступному вигляді: ім’я запису.ім’я елементу У нашому прикладі для першого запису звернення матимуть вигляд: АВБ.Н; АВБ.П ; АВБ.О. Записи, як і інші дані, оголошуються в розділі описів і використовуються в розділі операторів. Оголошені записи можна робити в розділі змінних VAR або з використанням розділу типів TYPE. Оголошені запису в розділі змінних має наступний вигляд: VAR _ ім’я запису: RECORD ім’я елемента 1: тип; ім’я елемента 2: тип; … ім’я елемента n: тип END; Тут службове слово RECORD (запис) виконує роль відкриваючого операторної дужки, END – закриваючого операторної дужки. Всередині – описуються елементи запису. Допускається замість імені запису вказувати список імен, тобто імена записів, поділені комами. Елементи запису разом з їх описом називаються полями запису. Для представленої відомості оголошення запису виглядає наступним чином: VAR АВБ, ВВВ, ДКЮ: RECORD Н: INTEGER; Ф: ARRAY [1..20] OF CHAR; О: ARRAY [1..3] OF INTEGER END; Де на прізвище визначений упакований масив з 20 елементів (зайві позиції у прізвищі можна заповнювати пробілами), на оцінки – масив з 3 елементів (3 оцінки). Розглянемо найбільш універсальну форму оголошення запису – з використанням розділу типів: TYPE _ ім’я типу: RECORD ім’я елемента 1: тип; ім’я елемента 2: тип; … ім’я елемента n: тип END; VAR _ ім’я запису: ім’я типу; Оголошення відомості, якщо дан тип ВІДОМІСТЬ, можна зробити наступним чином: TYPE ВІДОМІСТЬ=RECORD Н: INTEGER; Ф: ARRAY [1..20] OF CHAR; О: ARRAY [1..3] OF INTEGER END; VAR АВБ, ВВВ, ДКЮ: ВІДОМІСТЬ; Елемент запису використовується в програмі у тому ж самому значенні, як і звичайна змінна. Таким чином, елемент запису можна вказувати як ліворуч оператора присвоювання, так і у виразах. Над елементом запису можна виконувати дії, які допустимі для даних його типу. Якщо елемент запису – цілий, то виконуються всі операції, допустимі для цілих даних. Так, для розглянутої відомості над елементами запису можна виконати, наприклад, наступні операції: – знайти семестрову рейтингову оцінку (суму трьох оцінок): S:=АВБ.О[1]+АВБ.О[2]+ АВБ.О[3] – ввести значення номера за порядком: READ(АВБ.Н) Звернення до запису в цілому, а не тільки до його елементів, допускається тільки в операторі присвоювання. Ліворуч і праворуч від знака присвоювання при цьому повинні використовуватися імена записів однакового типу. Оператор приєднання Як зазначалось, звернення до елементів запису відбувається за допомогою уточненого імені. Оператор приєднання (WITH) дозволяє спростити звернення до елементу запису. Ім’я запису виноситься у заголовок оператора приєднання, а у блоці використовується тільки імена елементів запису. Загальна форма оператора приєднання: WITH _ ім’я запису _ DO BEGIN оператори, які містять імена елементів запису END Наприклад, для розглянутого запису (списку студентів з їх оцінками) операції присвоювання, підсумовування і введення можна об’єднати в один оператор: … WITH АВБ DO BEGIN S:=О[1]+О[2]+О[3]; READ(Н) END; … |