Багатовимірні масиви

У повсякденному житті досить часто доводиться мати справу з інформацією, яка представлена в табличній формі. Наприклад, результат діяльності деякої фірми, яка торгує автомобілями, може бути представлений у вигляді табл. 5.7.

Таблиця 5.7

Січень Лютий Травень Листопада Грудень
ВA3 2106
ВA3 2107
ВA3 2108
ВA3 2109
ВАЗ 2110
ВАЗ 2111

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

vaz2106: array [1..12] of integer;
vaz2107: array [1..12] of integer;
vaz2108: array [1..12] of integer;
vaz2109: array [1..12] of integer;
vaz2110: array [1..12] of integer;
vaz2111: array [1..12] of integer;

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

jan: array [1..6] of integer;

feb: array [1..6] of integer;

mar: array [1..6] of integer;
dec: array [1..6] of integer;

У цьому випадку кожен масив призначений для зберігання інформації про кількість проданих за місяць автомобілів, причому значення елемента масиву відображає продана кількість автомобілів однієї марки.
Якщо вся таблиця містить однорідну інформацію, наприклад, тільки цілі числа, то така таблиця може бути представлена як двовимірний масив.
У загальному вигляді інструкція оголошення двовимірного масиву виглядає так:
Ім’я: array [НіжняяГраніца1..ВерхняяГраніца1,
НіжняяГраніца2..ВерхняяГраніца2] of Тип
де:

  • Ім’я – ім’я масиву;
  • array – слово мови Delphi, яке вказує, що оголошений елемент даних є масивом;
  • НіжняяГраніца1, ВерхняяГраніца1, НіжпяяГраніца2, ВерхняяГраніца2 – цілі константи, що визначають діапазон зміни індексів і, отже, число елементів масиву;
  • Тип – тип елементів масиву.

Табл. 5.7 може бути представлена ??у вигляді двовимірного масиву наступним чином:
itog: array [1..12, 1..6] of integer
Кількість елементів двовимірного масиву можна обчислити за формулою:
(ВГ1-НГ1 + 1) х (Вг2-НГ2 + 1):
де:

    • ВГ1 і Вг2 – верхня межа першого і другого індексів;
    • НГ1 і НГ2 – нижня межа першого і другого індексів. Таким чином, масив itog складається з 60 елементів типу integer.

Для того щоб використовувати елемент масиву, потрібно вказати ім’я масиву та індекси елемента. перший індекс зазвичай відповідає номеру рядка таблиці, другий – номеру колонки. Так, елемент itog [2,3] містить число проданих в березні (третій місяць) автомобілів марки ВАЗ 2107 (дані про продаж ВАЗ 2107 знаходяться у другому рядку таблиці).
При роботі з таблицями (Масивами) зручно використовувати інструкцію for. Наприклад, фрагмент програми, обчислює кількість проданих за рік автомобілів одного найменування, виглядає так:

s : = 0;
for j: = 1 to 12 do
s : = S + itog [2, j];

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

s: = 0;
for i: = 1 to 6 do // шість моделей автомобілів
for j: = 1 to 12 do // 12 місяців s: = s + itog [i, j];

У наведеному фрагменті програми кожного разу, коли внутрішній цикл (цикл по j) завершується, в зовнішньому циклі значення i збільшується на одиницю і внутрішній цикл виконується знову. Таким чином, до поточного значення змінної s послідовно додаються значення елементів масиву itog: itog [l, l], itog [l, 2], …, itog [l, 12], itog [2, l], itog [2,2], …, itog [2,12] і т. д.
Як приклад розглянемо програму, яка обробляє результати спортивних змагань літньої олімпіади в Сіднеї, 2000 г. Вихідні дані представлені в табл. 5.8.

Таблиця 5.8. Результати олімпіади 2000 року в Сіднеї

Країна Золотих Срібних Бронзові
Австралія 16 25 17
Білорусь 3 3 11
Великобританія 11 10 7
Німеччина 14 17 26
Італія 13 8 13
Китай 28 16 15
Корея 8 9 11
Куба 11 11 7
Нідерланди 12 9 4
Росія 32 28 28
Румунія 11 6 9
США 39 25 33
Франція 13 14 11
Японія 5 8 5

Програма повинна обчислити загальна кількість медалей, завойованих представниками кожної країни, і відповідне кількість очок (балів), яке обчислюється за наступним правилом: за кожну золоту медаль команда отримує сім очок, за срібну – шість очок, за бронзову – п’ять очок.
Вид діалогового вікна програми наведено на рис. 5.20.

Рис. 5.20. Діалогове вікно програми Підсумки олімпіади

Для введення вихідних даних і відображення результату використовується компонент StringGrid, властивості якого наведені в табл. 5.9.

Таблиця 5.9. Значення властивості компонента StringGrid1

Властивість Значення
Name Tab1
ColCount 6
RowCount 14
FixedCols 0
FixedRows 1
Options. goEditing TRUE
DefaultColWidth 65
DefaultRowHeight 14
GridLineWidth 1

Осередки першої зафіксованої рядки таблиці використовуються в якості заголовків колонок таблиці. Під час створення форми додатка можна встановити значення елементів масиву cells, т. к. елементи масиву доступні тільки під час роботи програми. Тому значення елементів масиву Сells, відповідних першому рядку таблиці, встановлює
процедура обробки події OnActivate (її текст приведений в лістингу 5.11), яке відбувається під час активізації форми додатка. Крім того, ця процедура вписує в першу колонку таблиці назви країн-учасниць змагань.

Лістинг 5.11. Ініціалізація таблиці

procedure TForml.FormActivate (Sender: TObject); begin
tabl.Cells [0,0] = 'Країна';

tabl.Cells [1,0] = 'Золотих';

tabl.Cells [2,0] = 'Срібних';

tabl.Cells [3,0] = 'Бронзові';

tabl.Cells [4,0] = 'Bcero';

tabl.Cells [5,0] = 'Балів';

tabl.Cells [0,1] = 'Австралія';

tabl.Cells [0,2] = 'Білорусія';

tabl.Cells [0,3] = 'Великобританія';

tabl.Cells [0,4] = 'Німеччина';

tabl.Cells [0,5] = 'Італія';

tabl.Cells [0,6] = 'Китай';

tabl.Cells [0,7] = 'Корея';

tabl.Cells [0,8] = 'Куба';

tabl.Cells [0,9] = 'Нідерланди';
tabl.Cells [0,10] - 'Росія';
tabl.Cells [0, ll]: = 'США';
tabl, Cells [0,12]: = 'Франція';
tabl.Cells [0,13]: = 'Японія';
end;

Програма обробки вихідної таблиці (лістинг 5.12) запускається клацанням миші на командній кнопці Підсумки (Buttoni).

Лістинг 5.12. Обробка двовимірного масиву

procedure TForml.ButtonlClick (Sender: TObject);

var
c, r: integer; // номер колонки і рядки таблиці
s: integer; // медалей у команди
р: integer; // очок у команди
m: integer; // номер рядка з максимальною кількістю очок
buf: array [0..5] of string; // буфер для обміну рядків
i: integer; // номер рядка. Використовується під час сортування
begin
for r: = l to tab1.rowcount do // обробити всі рядки

begin s: = 0;
// обчислюємо загальна кількість медалей

for c: = l to 3 do
if tabl.cells [c, r] <> ''
then s: = s + StrToInt (tab1.cells [c, r])

else tabl.cells [c, r]: = '0'; // обчислюємо кількість очок

p: = 7 * StrToInt (tab1.cells [l, r]) +

6 * StrToInt (tabl.cells [2, r])

+ 5 * StrToInt (tabl.cells [3, r]};
// висновок результату
tabl.cells [4, r]: = IntToStr (s); // медалей

tabl.cells [5, r]: = IntToStr (p); // очок

end;
// сортування таблиці по спадаючій відповідно
// з кількістю балів (по вмісту 5-го стовпчика)
// сортування методом вибору
for r: = l to tab1.rowcount-1 do
begin
m: = r; // максимальний елемент - в r-му рядку

for i: = r to tabl.rowcount-1 do
if StrToInt (tabl.cells [5, i]) > StrToInt (tabl.cells [5, m])

then m: = i;
if r <> m then
begin // обміняємо г-у і m-ю рядки таблиці

for c: = 0 to 5 do begin
buf [з]: = tab1.Cells [c, r];
tab1.Cells [c, r]: = tabl.Cells [c, m];
tab1.Cells [c, m]: = buf [c];
end;

end;

end;

end;

Спочатку для кожної країни програма обчислює загальну кількість медалей і відповідну кількість очок. Потім, використовуючи метод простого вибору, програма виконує сортування таблиці по спадаючий кількості набраних очок. Під час сортування для обміну рядків таблиці використовується строковий масив buf, індекс якого, як і індекс шпальти таблиці, змінюється від нуля до п’яти (див. інструкцію оголошення масиву в тексті програми). Такий прийом дозволяє найбільш просто скопіювати замещаемой рядки в буфер і заміщення рядка вмістом буфера.
На рис. 5.21 приведено діалогове вікно програми після завершення процесу обробки масиву.

Рис. 5.21. Вікно програми Підсумки олімпіади