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

3. Приклад розв’язання задачі на еом (варіант №30)

3.1. Розробка алгоритму вирішення

В даній роботі у нас розмірність матриці заздалегідь не відома. Чи складає це істотне розходження? Так. Якщо ми перевіримо функціонування алгоритму цієї роботи при різних значеннях розмірності (S), то ми переконаємося, що коректно він спрацьовує тільки при непарних значеннях S. При парних значеннях верхня половина матриці формується правильно, а в нижній половині область ненульових значень буде захоплювати також і самі діагоналі, що не відповідає умовам завдання. Тому для цієї роботи варто переглянути алгоритм.

Для елемента, що лежить на головній діагоналі, індекси задовольняють умові: L=R, на побічній - R=S-L-1. Отже, для верхньої половини умова попадання в ненульову область: L < R < S-L-1, а для нижньої: S-L-1 < R < L. Або, узагальнюючи: min(L,S-L-1) < R < max(L,S-L-1) . У схемі алгоритму, що приведений на малюнку 1, ми використовуємо саме цю умову. До того ж у схемі відображено поділ програми на дві функції: головну функцію - main(), що виконує виділення пам'яті для матриці, виклик функції заповнення матриці і вивід результату, і функцію fill(), що виконує заповнення матриці за заданими правилами.

У цій роботі трохи ускладнимо алгоритм, додавши в нього перевірку значення S, що введено оператором (блоки 3 - 8). Нижня границя для значення S - 1, оскільки матриця нульової або негативної розмірності просто не має змісту.

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

3.2. Представлення матриці в пам'яті

Для даної задачі можливі три варіанти розміщення в пам'яті і представлення матриці в програмі. В усіх трьох варіантах очевидно, що загальний обсяг пам'яті для розміщення даних матриці повинен бути S2 елементів типу int.

Варіант 1 показаний на рис.12.2

Рисунок 12.2 - Розміщення в пам'яті. Варіант 1.

Для даних матриці виділяється необхідний об’єм пам'яті. У програмі виводиться покажчик на початок цієї області. Тип цього покажчика - int*. Таким чином, матриця є одномірним масивом і для того, щоб по номеру рядка (L) і стовпця (R) визначити індекс в одномірному масиві (N) варто виконати обчислення: N=L*S+R.

 Варіант 2 показаний на рис.12.3

Рисунок 12.3 - Розміщення в пам'яті. Варіант 2



Пам'ять для даних матриці виділяється так само, як і в попередньому випадку. Але додатково виділяється пам'ять для одномірного масиву розмірності S, елементи якого мають тип int* (покажчик на ціле). Покажчик на початок цього масиву має тип int** (покажчик на покажчик на ціле). В

Рисунок 12.1 - Логічна схема програми

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

    Варіант 3 показаний на рис.12.4

Рисунок 12.4 - Розміщення в пам'яті. Варіант 3

Цей варіант відрізняється від попередніх тим, що для кожного рядка матриці пам'ять виділяється окремо (S областей пам'яті по S елементів у кожній), і в масив покажчиків заносяться покажчики на відповідні області. Таким чином, матриця необов'язково займає суміжні області пам'яті. Можна звертатися до даних матриці, вказуючи два індекси. Виділення пам'яті (і відповідно - звільнення) потрібно виконувати в циклі. Варіант 1 забезпечує економію пам'яті, а варіанти 2 і 3 - можливість "природного" звертання до елементів матриці. Варіант 3 дозволяє раціональніше використовувати пам'ять, ніж варіант 2, але варіант 2 алгоритмічно більш простий. Ми покажемо реалізації алгоритму для варіантів 1 і 3.