Двумерные массивы. Особенности работы с двумерными массивами
До сих пор мы рассматривали задачи, в которых приходилось обрабатывать последовательности однотипных значений. Последовательность имела имя, а каждое ее значение имело свой порядковый номер, по которому компьютер к нему обращался. В жизни часто приходится иметь дело с таблицами, содержащими большее количество полей. Например, таблица, содержащая данные о весе учеников в параллели восьмых классов:1 | 2 | 3 | 4 | ……………………………………… | n-1 | n | |
8a | 50.8 | 55.9 | 40.3 | 45.8 | ……………………………………… | 45.8 | 50.9 |
8б | 45.6 | 43.0 | 50.8 | 48.7 | ……………………………………… | 49.0 | 47.7 |
8в | 50.7 | 48.9 | 45.8 | 44.9 | ……………………………………… | 45.0 | 45.0 |
8г | 54.0 | 56.9 | 45.7 | 40.7 | ……………………………………… | 43.8 | 54.0 |
Чтобы обратиться к элементу такой таблицы, необходимо указать наименование класса и номер ученика в этом классе. Теперь элемент имеет два номера: «номер строки таблицы» и «номер столбца таблицы». Для работы с таблицами такого вида используется - двумерный массив. Двумерные массивы часто называют матрицами.
Описание двумерных массивов
Описание двумерных массивов аналогично описанию одномерных.Var <идентификатор>: array[<типы индексов>] of <тип элементов>;
Идентификатор – имя массива.
У элементов двумерного массива два индекса (номера), поэтому, в качестве типов индексов указывают интервалы значений, которые может принимать номер строки и номер столбца.
Например:
Var Ves : array[1..4, 1..35] of real;
Здесь описан массив, максимальное количество элементов которого 4 * 35 = 140 штук, и все они являются данными вещественного типа real. Такой массив как раз подойдет для хранения таблицы данных о весе учащихся восьмой параллели.
В памяти компьютера выделится ячейка, которая разобьется на 140 разделов, размером по 6 байт. В них, после ввода массива, будут расположены данные Ves[1, 1], Ves[1, 2], … Ves[1, n], Ves[2, 1], Ves[2, 2] и т.д. Весь массив будет занимать 840 байтов памяти.
Не обязательно, что все ячейки памяти будут заполнены. Это зависит от того, как будет вводиться массив.
Ввод и вывод двумерного массива
Ввод и вывод массива осуществляются покомпонентно. Каждый элемент массива вводится оператором read и, аналогично, каждый элемент массива выводится оператором write.Var A : array[1..10, 1..10] of integer;
i, j, n, m : integer;
Begin
Read (n, m); {ввели количество строк и столбцов массива}
For i := 1 to n do {перебираем номера строк}
For j := 1 to m do read (a[i, j]); {от 1 до последнего каждый элемент вводится с клавиатуры: вначале элементы первой строки, затем второй и т.д.}
For i := 1 to n do begin
For i := 1 to n do write (a[i, j], ' '); {вывод элементов i-ой строки}
Writeln; {переход на новую строку}
end;
End.
Действия над элементами массива
Каждый элемент массива имеет свое уникальное имя, которое складывается из имени массива и порядкового номера элемента:A[1, 6], A[4, 2], A[i, j], A[n div 2, 4], A[n - 2, m - 7], A[n, m] и т.д.
Так к ним и надо обращаться в программе.
В основном все задачи на двумерные массивы решаются аналогично, как и на одномерные. Только не следует забывать, что элемент имеет два индекса, а таблица состоит из строк и столбцов.
Пример. В школе проводилась олимпиада по математике среди учащихся восьмых классов. В ней приняли участие по n представителей от каждого класса. Данные об олимпиаде – это количество баллов, набранное каждым из учеников.
Необходимо посчитать:
а) средний балл по параллели;
б) количество учеников в параллели, не набравших ни одного балла;
в) максимальный балл по параллели;
г) номера победителей по параллели;
д) номера победителей в каждом из классов.
Дано: A – массив, значениями которого будут баллы участников олимпиады (элементы типа byte);
n – количество классов в восьмой параллели ( byte);
m – количество представителей от класса (byte).
а) Найти: Sball – средний балл, набранный в параллели (real).
Решение:
Чтобы найти средний балл, нужно сложить баллы, набранные каждым из учеников, то есть, найти сумму элементов массива (Oball) и разделить ее на количество всех учеников (m * n).
Программа:
Var A : array[1..10, 1..35] of byte;
n, m, i, j : byte; Oball : integer; Sball : real;
Begin
Writeln ('введите количество классов в параллели'); Read (n);
Writeln ('введите количество участников от каждого из классов'); Read (m);
For i := 1 to n do For j := 1 to m do begin
Writeln ('введите балл ', j, '-го ученика в ', i, '-ой группе');
Read (A[i, j]);
end;
Oball := 0;
For i := 1 to n do For j := 1 to m do Oball := Oball + A[i, j];
Sball := Oball / (n * m);
Writeln ('Средний балл по параллели- ', Sball : 4 : 2);
End.
б) Найти: Kol - количество учеников в параллели, не набравших ни одного балла (byte).
Решение:
Решение задачи сводится к поиску элементов массива, значение которых равно нулю. Чтобы найти количество, нужно увеличивать переменную kol на единицу, как только обнаружится элемент массива равный нулю. Поэтому нужно просмотреть все элементы массива и сравнить их с нулем.
Программа:
Var A : array[1..10, 1..35] of byte;
n, m, i, j, kol : byte;
Begin
Writeln ('введите количество классов в параллели'); Read (n);
Writeln ('введите количество участников от каждого из классов'); Read (m);
For i := 1 to n do For j := 1 to m do begin
Writeln ('введите балл ', j, '-го ученика в ', i, '-ой группе'); Read (A[i, j]);
end;
kol := 0;
For i := 1 to n do For j := 1 to m do if A[i, j] = 0 then kol := kol + 1;
Writeln ('Ни одного балла не набрали ', kol, ' учеников');
End.
в) Найти: Max – максимальный балл по параллели (byte).
Решение:
Решение задачи сводится к нахождению максимального элемента массива.
Программа:
Var A : array[1..10, 1..35] of byte;
n, m, i, j, max : byte;
Begin
Writeln ('введите количество классов в параллели'); Read (n);
Writeln ('введите количество участников от каждого из классов'); Read (m);
For i := 1 to n do For j := 1 to m do begin
Writeln ('введите балл ', j, '-го ученика в ', i, '-ой группе'); Read (A[i, j]);
end;
max := A[1, 1];
For i := 1 to n do For j := 1 to m do if A[i, j] > max then max := a[i, j];
Writeln ('Максимальный балл по параллели - ', max);
End.
г) Найти: i , j – номера победителей по параллели (byte).
Решение:
Пусть max – максимальный балл по параллели. Это переменная типа byte, значение которой мы уже умеем находить. Чтобы найти номера победителей, достаточно вывести на экран номера строк и столбцов элементов массива равных значению переменной max.
Программа:
Var A : array[1..10, 1..35] of byte;
n, m, i, j, max : byte;
Begin
Writeln ('введите количество классов в параллели'); Read (n);
Writeln('введите количество участников от каждого из классов'); Read (m);
For i := 1 to n do For j := 1 to m do begin
Writeln ('введите балл ', j, '-го ученика в ', i, '-ой группе'); Read (A[i, j]);
end;
max := A[1, 1];
For i := 1 to n do For j := 1 to m do if A[i, j] > max then max := A[i, j];
Writeln ('Номера победителей');
Writeln ('N группы N ученика ');
For i := 1 to n do For j := 1 to m do if A[i, j] = max then
writeln (' ', i, ' ', j);
End.
е) Найти: i, j – номера победителей в каждом из классов.
Решение:
В нашем массиве каждая строка содержит результаты олимпиады в группе представителей отдельного класса. Для решения задачи необходимо найти максимальный балл в каждой строке и вывести номера победителей только данной строки. Например, решение задачи для данных первой строки, можно отразить в следующем фрагменте:
i := 1; {обрабатываем первую строку}
max := A[i, 1]; {в качестве «максимального» выбираем первый элемент в рассматриваемой строке}
For j := 1 to m do {перебираем номера элементов в рассматриваемой строке с номером i, равным 1}
if A[i, j] > max then max := A[i, j]; { ищем максимальный элемент в строке}
Write ('Номера победителей ', i, '-ой строки: ');
For j := 1 to m do if A[i, j] = max then write (j, ', '); {выводим номера элементов, равных по величине значению переменной max}
Аналогичным образом, необходимо обработать все строки массива. Переменная i, отвечающая за номер строки, должна постепенно принять все свои значения от 1 до n. Предложенный фрагмент следует сделать телом цикла по параметру i.
Программа:
Var A : array[1..10, 1..35] of byte;
n, m, i, j, max : byte;
Begin
Writeln ('введите количество классов в параллели'); Read (n);
Writeln ('введите количество участников от каждого из классов'); Read (m);
For i := 1 to n do For j := 1 to m do begin
Writeln ('введите балл ', j, '-го ученика в ', i, '-ой группе'); Read (A[i, j]);
end;
For i := 1 to n do begin
max := A[i, 1];
For j := 1 to m do if A[i, j] > max then max := a[i, j];
Write ('Номера победителей ', i, '-ой строки: ');
For j := 1 to m do if A[i, j] = max then write (j, ', ');
writeln;
end;
End.
Формирование двумерных массивов
Заполнение двумерных массивов производится не только в результате ввода с клавиатуры. Иногда решение задачи требует формирование двумерного массива по определенному принципу. Тогда заполнение массива следует производить при помощи оператора присваивания.Пример 1. Сформировать таблицу умножения, имеющую вид:
1 2 3 .. m
2 4 6 .. 2m
3 6 9 .. 3m
. . .
. . .
n 2n 3n .. mn
Дано: n – количество строк массива (integer);
m – количество столбцов массива (integer).
Найти: А – массив-«таблица умножения».
Решение:
Чтобы заполнить массив, необходимо обратиться к каждому из его элементов A[i, j], где i – номер строки (от 1 до n), а j – номер столбца (от 1 до m). Это можно осуществить с помощью вложенных циклов с параметром. Заполнять А[i, j] мы будем произведением его номера строки и столбца.
Программа:
Var n, m, i, j : integer;
A: array[1..30, 1..30] of integer;
Begin
Writeln ('введите количество строк и столбцов'); Read (n, m);
For i := 1 to n do For j := 1 to m do A[i, j] := i * j;
Writeln ('Таблица умножения');
For i := 1 to n do begin
For j := 1 to m do write (A[i, j], ' ');
writeln;
end;
End.
Пример 2. Сформировать таблицу степеней, имеющую вид:
1 2 3 ... m
1 4 9 ... m2
1 8 27 ... m3
1 16 81 ... m4
. . .
. . .
1n 2n 3n ... mn
Дано: n – максимальный показатель степени в таблице (integer);
m – максимальное основание степени (integer).
Найти: А – массив, элементами которого будут степени чисел (longint).
Решение:
Чтобы заполнить массив A, необходимо обратиться к каждому из элементов A[i, j]. Очевидно, что элементы заполняются по формуле A[i, j] :=j i . Такой массив удобно заполнять по столбцам. Если рассматривать отдельный столбец массива, то можно заметить, что в нем каждый последующий элемент равен предыдущему, умноженному на номер столбца. Для заполнения фиксированного столбца с номером j можно применить следующий фрагмент программы.
Программа:
Var A : array[1..10, 1..10] of longint;
n, m, i, j : byte;
Begin
Read (n, m);
For j := 1 to m do begin
A[1, j] := j;
For i := 2 to n do A[i, j] := A[i - 1, j] * j;
end;
For i := 1 to n do begin
For j := 1 to m do Write (A[i, j], ' ');
writeln;
end;
End.