Массивы, положение элементов в которых описывается двумя индексами, называются двумерными. Их можно представить в виде прямоугольной таблицы или матрицы.
Рассмотрим матрицу А размерностью 2*3, то есть в ней будет две строки, а в каждой строке по три элемента:
Каждый элемент имеет свой номер, как у одномерных массивов, но сейчас номер уже состоит из двух чисел - номера строки, в которой находится элемент, и номера столбца. Таким образом, номер элемента определяется пересечением строки и столбца. Например, a12 - это элемент, стоящий в первой строке и во втором столбце.
Существуют несколько способов объявления двумерного массива.
Способ 1. В Паскале двумерный массив можно описать как одномерный, элементами которого являются одномерные массивы. Например, для матрицы А, приведённой выше:
Const n = 2; m = 3; Type omyarray = Array[1..m] Of <тип элементов >; dmyarray = Array[1..n] Of omyarray; Var v : omyarray; a : dmyarray;
В данном случае переменная v объявлена как одномерный массив из трёх элементов вещественного типа. Переменная а описана как двумерный массив из двух строк, каждую из которых включено по три элемента.
Способ 2. Описание массива А можно сократить, исключив определение типа omyarray в определении типа dmyarray:
Const n = 2; m = 3; Type dmyarray = Array[1..n, 1..m] Of <тип элементов>; Vara : dmyarray.
Способ 3. Ещё более краткое описание массива А можно получить, указывая имя массива и диапазоны изменения индексов для каждой размерности массива:
Const n = 2; m = 3; Type dmyarray = Array[1..n, 1..m] Of <тип элементов >;
Var a : dmyarray.
Если указанный тип используется для определения одного массива в программе, то удобно объявление массива в разделе описания переменных:
Var a: Array [1..n, 1..m] Of < тип элементов >.
Рассмотренные выше методы решения задач обработки одномерных массивов могут применяться для обработки двумерных массивов. Поскольку положение элемента в двумерном массиве описывается двумя индексами [первый - номер строки, второй - номер столбца], программы большинства матричных задач строятся на основе вложенных циклов. Обычно внешний цикл работает по строкам матрицы, то есть с его помощью выбирается требуемая строка матрицы, а внутренний цикл - по столбцам матрицы, то есть здесь выбирается нужный элемент из выбранной уже строки. Для задания значений элементам массива могут быть использованы операторы присваивания и операторы ввода данных.
Пример 1
В приведённом ниже примере осуществляется ввод и вывод двумерного массива А размерностью 10*15. Формирование и вывод массива описаны в виде двух процедур, которые вызываются последовательно из основной программы. Надо заметить, что формирование двумерного массива можно осуществлять всеми тремя способами, описанными для одномерных массивов, то есть: ввод с клавиатуры, через генератор случайных чисел или с помощью файла. Пусть в нашем примере элементы задаются генератором случайных чисел.
Program Example_45; Const n = 2; m = 15; Type dmyarray = Array[1..n., 1..m] Of Integer; Var A : dmyarray;
Procedure Init(Var x: dmyarray); {процедура формирования массива} Var i, j : Integer; Begin For i:=1 To n Do For j:=1 To m Do x[i,j]:=-25+Random(51); End;
Procedure Print(x: dmyarray); {процедура вывода массива на экран} Var i, j : Integer; Begin For i:=1 To n Do Begin {ввод i-ой строки массива} For j:=1 To n Do Write(x[i,j]:5); Writeln; {переход на начало следующей строки} End;
При решении задач с двумерными массивами можно выделить несколько видов задач.
Найти сумму элементов
Можно найти сумму всех элементов, можно только некоторых, которые удовлетворяют данному условию. Но мы рассмотрим более сложный пример.
Пример 2
Сформировать одномерный массив, каждый элемент которого равен сумме отрицательных элементов соответствующей строки заданной целочисленной матрицы.
Решение
Опишем одномерный массив, размерность которого равна количеству строк в двумерном массиве.
Const n = 10; m = 15; Type omyarray = Array[1..n] Of Integer; dmyarray = Array[1..n, 1..m] Of Integer Var B : omyarray; A : dmyarray;
Формирование одномерного массива по заданному правилу опишем в виде процедуры. Ей будем передавать два параметра - двумерный массив и одномерный, который является результатом. В теле процедуры будут использоваться вложенные циклы. Внешний цикл в ней определяет номер строки, который совпадает с номером элемента одномерного массива. Здесь же задаются начальные значения элементов одномерного массива, равные 0. Во внутреннем цикле анализируется каждый элемент выбранной строки, и если он отрицательный, то добавляется к сумме всех предыдущих отрицательных элементов выбранной строки матрицы.
Procedure Sum(x: dmyarray; Var y: omyarray); Var i, j : Integer; Begin For i:=1 To n Do Begin y[i]:=0; {задание начальных значений элементов массива суммы} For j:=1 To m Do{накопление суммы отрицательных} If x[i,j]<0 Then y[i]+x[i,j]; End; End;
В основной программе обращаемся к процедуре Sum(A,B) и остается только вывести на экран одномерный массив В, в котором записаны суммы отрицательных элементов каждой строки.
Нахождение количества элементов с данным свойством
Задачи на нахождение номеров элементов с заданными свойствами и на нахождение количества таких элементов во всём массиве останутся практически такими же. В них только добавится второй цикл или вывод двух индексов вместо одного.
Пример 3
Найти максимальный элемент массива и его индексы.
Решение
Так как элементы могут повторяться, то договоримся, что будем запоминать только индексы первого максимального элемента. Опишем процедуру, которой передаётся массив, и её результатом является значение максимального элемента и индексы первой встречи такого значения.
Procedure Maximum(x: dmyarray; Var max, maxi, maxj: Integer); Var i,j: Integer; Begin {начальные значения} max:=x[1,1]; maxi:=1;maxj:=1; For i:=1 To n Do For j:=1 To m Do If x[i,j]>max Then {присвоение новых значений} Begin max:=x[i,j]; maxi:=i;maxj:=j; End; End;
Пример 4
Найти количество отрицательных элементов в каждой строке.
Решение
Рассмотрим несколько способов решения этой задачи.
Способ 1 - количество элементов каждой строки хранить в одномерном массиве соответствующей размерности. Тогда можно описать такую процедуру:
Procedure Q_1(x: dmyarray; Var y: omyarray); Var i, j : Integer; Begin For i:=1 To n Do Begin y[i]:=0 For j:=1 To m Do If x[i,j]<0 Then Inc(y[i]); End; End;
Способ 2 - использовать счётчик, находить количество элементов строки и выводить значение на экран. Тогда:
Procedure Q_2(x: dmyarray); Var i, j, k : Integer; Begin For i:=1 To n Do Begin k:=0 For j:=1 To m Do If x[i,j]<0 Then Inc(k); Writeln(i,' - ',k); {вывод номера строки и количества заданных элементов} End; End;
Работа с несколькими массивами
Пример 5
Составить программу вычисления произведения двух квадратных целочисленных матриц А и В размером 5*5 соответственно. Элементы результирующей, также целочисленной, матрицы С (размером 5*5) определяются по формуле
c[i, j] =
где n - размерность матриц А и В.
Решение
Формирование матриц будем производить с помощью генератора случайных чисел, вычисление элементов результирующей матрицы С - с помощью вложенных циклов, где во внутреннем цикле (по параметру k) будет накапливаться сумма, определяющая элемент с[i,j].
Program Exampl_46; Const n = 5; Type dmyarray = Array[1..n, 1..n] Of Integer; Var A, B, C : dmarray;
Procedure Init(Var x: dmyarray);
...
Procedure Print(x: dmyarray);
...
Procedure Mult(x,y: dmyarray; Var z: dmyarray); Var k, i, j : Integer; Begin For i:=1 To n Do For j:=1 To m Do Begin z[i,j]:=0; For k:=1 To n Do z[i,j]:=z[i,j]+x[i,j]*y[k,j]; End; End;
Определить, отвечает ли заданный массив некоторым требованиям
Пример 6
Определить, есть ли в данном массиве элемент, равный 0.
Решение
Опишем логическую функцию, значение которой равно истине, если такой элемент есть, и ложь - в противном случае. Самый простой способ - это просматривать элементы, и если найден искомый, то присвоить функции значение True, иначе - False.
Function Check1(x: dmyarray): Boolean; Var i, j : Integer; t: Boolean; Begin t:= true; {предполагаем, что искомого элемента в массиве нет} i:=1; {начальные значения} While t And (i<=n) Do Begin j:=1; While (j<=m) And (x[i,j]<>0) Do Inc(j); t:=(j=m+1); {определяем, найден ли искомый элемент, если просмотрена вся строка, то значение j=m+1 и t:= True, иначе элемент не найден и t:= False} Inc(i); End; check1:=not t; {t=False, если элемент в массиве есть поэтому значению функции присваиваем not t} End;
Пример 7
Определить, является ли данный квадратный массив симметричным относительно своей главной диагонали.
Решение
Если он является симметричным, то для него выполняется равенство a[i, j] = a[i, j] для всех i = 1,...,n и j = 1,...,n при условии, что i>j. Поэтому можно составить следующую функцию:
Function Check2(x: dmyarray): Boolean; Var i, j : Integer; t : Boolean; Begin t:= True; {предположим, что матрица симметрична} i:=2; While t And (i<n) Do Begin j:=1; While (j<i) And (x[i,j]=x[j,i]) Do Inc(j); t:=(j=i); Inc(i); End; Check2:=t; End;
Таким образом, если встретится хотя бы одна такая пара, что соответствующие элементы не будут равны, то значение функции будет ложь(false)