Глава 11. Одномерные и двумерные массивы

advertisement
Глава 11. Одномерные и двумерные массивы
Раздел описания типов
В разделе описания типов пользователь может определять свои типы
данных, присваивая каждому из них определенный идентификатор.
Синтаксис данного раздела описан на рис. Рис. 1.
Рис. 1. Синтаксическая диаграмма для раздела описания типов
Пример 11.1.
Используя
раздел
описания
типов
можно
переопределить имена существующих типов данных.
Type int=integer; {к целому типу теперь можно будет
обращаться}
float=real;
{через идентификатор int, к вещественному –
}
Symbol=char; {через float, к символьному – через symbol}
Var x:int;
Rez:float;
Ch:symbol;
Чаще всего раздел type используют для определения идентификаторов
структурированных типов данных. Хотя введение идентификатора типа не
является обязательным, это позволяет улучшить читабельность программы и
уменьшает вероятность внесения ошибок при наборе, а в некоторых случаях
бывает просто необходимым. Описание массива x, содержащего 40
элементов целого типа возможно в разделе описания переменных:
Var x:array[1..40] of integer;
Однако, программа будет более понятной, если использовать разделы
описания констант и типов:
Const NMax = 40;
Type TArray = array[1..NMax] of integer;
Var x:TArray;
Определение пользовательского типа TArray, позволит использовать
его для определения новых массивов, структура которых аналогична
структуре массива x. Введение константы
NMax позволит уменьшить
вероятность внесения ошибок в программу при ее изменении и доработке,
т.к. отпадет необходимость всегда помнить, что в массиве именно 40
элементов, а не какое-то другое количество.
Пример 11.2
Не используем описания типов.
Используем раздел type.
Var x:array[1..4] of byte;
Type
z:string[10];
TArray
=
array[1..4]
of
byte;
y:array[1..4] of Byte;
TName = string[10];
a:array[1..10] of string[10]; Var x:TArray;
Присваивание
x:=y
при
таком
описании будет недопустимо.
z:TName;
y:TArray;
a:array[1..10] of TName;
Присваивание x:=y будет допустимо.
Описание одномерных массивов
Массив – регулярный тип данных; совокупность пронумерованных
однотипных элементов, имеющих общее имя.
Название регулярный тип массивы получили за то, что в них
объединены однотипные (логически однородные) элементы, упорядоченные
(урегулированные)
по
индексам,
определяющим
положение
каждого
элемента в массиве.
Например, введем 30 целых чисел в диапазоне от 21 до 50 и объединим
их общим именем А.
Получается таблица, состоящая из одной строки данных. Такие
таблицы называются линейными.
Таблица 1. Пример линейной таблицы
№
1
2
3
29 30
А 21 22 23
49 50
Для хранения подобных таблиц используют одномерные массивы
(векторы). Количество элементов в массиве всегда конечно.
Чтобы обратиться к отдельному элементу таблицы, надо указать
индекс (номер). Например, элемент с индексом 3 равен 23.
Объявление одномерных массивов
Массив можно описать разными способами:
1. В разделе описания переменных
Var <имя массива>:Array [<тип индекса>] Of <тип элементов>;
Тип индекса – порядковый тип, кроме Integer. Часто используют
интервальный тип (указывают допустимый диапазон значений). При
указании диапазона начальный индекс не должен превышать конечный. Тип
элементов массива может быть любым (стандартным или описанным ранее).
Число элементов массива фиксируется при описании и в процессе
выполнения программы не меняется.
2. В разделе описания типов
Type <имя типа> = Array [<тип индекса>] Of <тип элементов> ;
Var <имя массива> : <имя типа> ;
3. В разделе констант (задание типизированной константы)
Const <имя массива>:Array [<тип индекса>] Of <тип элементов>
= (<список элементов>);
Пример 11.3. Способы описания массивов.
1. Var А:Array [1..30] Of Byte;
При
описании
массива
можно
использовать
объявленные константы:
Const NMax=30;
Var А:Array [1..Nmax] Of Byte;
2. Type TArray= Array [1..30] Of Byte;
Var A: TArray;
предварительно
В результате описаний 1-2 на этапе трансляции программы будет
выделена память под массив А размером 30 байт.
3. Const A:Array [1..30] Of Byte=(21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50);
В описании 3 происходит не только выделение памяти под массив А
размером в 30 байт, но и выполняется присваивание элементам значений
элементам массива.
4. Const A:Array[-2..2] Of Char =(‘1’,’2’,’3’,’4’,’5’);
В описании 4 задается массив из пяти элементов символьного типа.
Индексы элементов
массива меняются в пределах от -2 до 2. Массив
содержит значения в диапазоне от ‘1’ до ‘5’.
При написании программы надо учитывать, что на хорошем выборе
типов данных (в частности, индексов) можно сэкономить – получить более
красивый, эффективный код, избавиться от «лишних» переменных и
действий соответственно.
Пример 11.4. Описать массив для хранения и последующей обработки
информации о количестве студентов группы, родившихся за каждый год в
период от 1993 до 1987 годы.
Описание массива может быть таким:
Var k:Array [1987..1993] Of Integer;
Для обращения к элементам массива надо указать имя массива, а затем
в квадратных скобках – индекс элемента. Например, обращение к 3-му
элементу массива: A[3]. Изменение значения пятого элемента: A[5]:=30;.
Для элемента массива в квадратных скобках может стоять не только
непосредственное значение индекса, но и выражение, приводящее к
значению индексного типа: A[k], A[N-k+1].
Ввод, вывод элементов одномерного массива
Заполнение и вывод массива можно выполнять только поэлементно,
т.е. необходимо организовать процесс с помощью цикла: сначала присвоить
значение 1-му элементу, затем 2-му и т.д.; то же самое и с выводом на экран
– сначала вывод 1-го элемента, затем 2-го и т.д.
Пример 11.5. Найти сумму 30 целых чисел.
Program summa_30;
Const N=30; {Максимальное количество элементов массива}
Var A: Array[1..N] Of Integer; i,S:Integer;
Begin
{Ввод
элементов
массива
с
клавиатуры.
N
–
количество
элементов}
For i:=1 To N Do Begin
Write (‘A[‘,i,']= '); Readln (А[i]);
End;
{Сумма элементов массива}
S:=0;
For i:=1 To N Do
S:= S + А[i];
WriteLn ('S=', S);
End.
Способы задания одномерных массивов:
1.
Задание значений элементов с клавиатуры.
2.
Задание с помощью генератора случайных чисел. Этот способ
заполнения массива используется тогда, когда мы знаем закономерность
распределения
значений.
Например,
надо
получить
выигрышную
комбинацию из 5 шаров, если номера шаров имеют значения от 1 до 36.
3.
Чтение из файла.
4.
Заполнение массива, элементы которого связаны некоторой
закономерностью.
Пример 11.6. Написать программу заполнения одномерного массива с
помощью генератора случайных чисел значениями от –10 до 10. Вывести
значения на экран.
Program init_rand;
Const Nmax=25; {максимальное количество элементов массива}
Type Tarray= Array[1..Nmax] Of Integer;
Var A:Tarray; i,n:Integer;
Begin
{Заполнение массива с помощью датчика случайных чисел}
Write(‘Введите количество элементов массива: ’);
ReadLn(n);
Randomize;
For i:=1 To n Do
А[i] := -10 + Random (21); {от -10 до 10}
{Вывод на экран первых n элементов массива}
For i:=1 To n Do
Write (А[i]:6);
end.
Пример 11.7. Заполнить одномерный массив с помощью датчика
случайных чисел таким образом, чтобы все его элементы были различны.
Program init_rand1;
Const NMax=50;
Type Mas = Array[1..NMax] Of Integer;
Var A:Mas; I, J, N:Byte; Fl:Boolean;
Begin
Write('Введите
N
');
ReadLn(N);
{количество
чисел
в
массиве}
randomize;
A[1] := -32768 + random(65535); {Значения от -32768 до
32767}
For I := 2 To N Do
Begin
Fl := True;
Repeat
A[i] := -32768 + random(65535);
J := 1;
While Fl and (j <= i - 1) Do
Begin Fl := A[i] <> A[j]; j := j + 1 End
Until Fl
End;
For i := 1 To N Do Write(A[i]:7); WriteLn
End.
Данная программа может привести к зацикливанию при некоторых
исходных данных и поэтому требует доработки. Например, если изменить
диапазон значений случайных чисел в пределах от одного до пяти, а размер
массива N задать не менее 6.
Пример 11.8. Составить программу чтения
значений элементов
одномерного массива из текстового файла arr.dat и вывода их на экран.
Количество элементов в файле заранее неизвестно, но не более 50.
Program init_file;
Const Nmax=50; {Количество элементов массива}
Var A:Array[1..Nmax] Of Integer; i,n:Integer; f:Text;
Begin
{Чтение
значений
элементов
одномерного
массива
текстового файла}
Assign (f,'arr.dat');
Reset (f); {Файл открывается для чтения}
n:=0; {Счетчик количества элементов массива}
While Not Eof (f) Do Begin
inc (n);
Read (f,А[n]);
End;
Close (f);
{Вывод массива на экран}
For i:=1 To n Do
Write (А[i], ‘ ‘);
End.
из
Если требуется считать определенное количество элементов из файла
или количество заранее известно, то в этом случае используется цикл с
параметром:
Значение переменной n (количество элементов) можно также ввести из
файла. Значение n должно находиться в пределах, которые установлены
типом индекса массива (или наоборот – тип индекса определяется
известными ограничениями).
...
Assign (f,'arr.dat');
Reset (f);
Read (f,n); {чтение количества элементов массива}
For i:=1 To n
Do
Read (f,А[i]); {заполнение массива из n элементов
значениями}
Close (f);
...
Пример 11.9. Что выполняет следующий фрагмент программы:
Program M;
Const N=50;
Var A : Array [1..N] Of Integer;
I : Integer;
Begin
For I:=1 To N Do
A[I]:=I*I
End.
Ответ: Заполняет массив таким образом, что значение каждого
элемента равняется квадрату его индекса.
Решение задач с использованием одномерных массивов
Пример 11.10. Переставить элементы массива в обратном порядке.
Const N=25;
Var A: Array[1..N] Of Integer; i,B:Integer;
Begin
{Ввод
элементов
массива
с
клавиатуры.
N
–
количество
элементов}
For i:=1 To N Do Begin
Write (‘A[‘,i,']= '); Readln (А[i]);
End;
{Перестановка элементов массива}
For i:=1 To N div 2 Do
Begin
B:=A[i]; A[i]:=A[N-i+1]; A[N-i+1]:=B;
End;
For i:=1 To N
Do {вывод массива}
Write(A[i]:6)
End.
Пример 11.11. Найти сумму четных элементов массива.
Const N=25;
Type Tarray=Array[1..N] Of Integer;
Var A:Tarray; i,S:Integer;
Begin
{Ввод
элементов
массива
с
клавиатуры.
N
–
количество
элементов}
For i:=1 To N Do Begin
Write (‘A[‘,i,']= '); Readln (А[i]);
End;
{Сумма элементов массива}
S:=0;
For i:=1 To N Do
If А[i] mod 2 = 0 Then {или not odd (А[i])}
S:= S + А[i];
WriteLn ('S=', S);
End.
Пример 11.12. Найти первый максимальный элемент массива и его
индекс.
Фрагмент программы (считаем, что все переменные описаны
правильно):
...
zmax:=А[1];
{Значение максимального элемента}
imax:=1;
{Индекс максимального элемента}
For i:=2 To n Do
If А[i] > zmax Then
Begin
zmax := А [i];
imax := i;
End;
или другой вариант:
...
imax:=1;
For i:=2 To n Do
If A[i] > A[imax] Then
imax := i;
zmax:= m[imax];
Пример 11.13. Найти количество положительных и отрицательных
элементов массива. Выбрать наиболее эффективный фрагмент.
Фрагмент программы 1:
Var i,k1,k2,n:Integer; A:Array[1..30] Of Integer;
Begin
...
k1:=0; {k1 – количество положительных элементов}
k2:=0; {k2 – количество отрицательных элементов}
For i:=1 To n Do
If A[i] > 0 Then Inc (k1)
Else If A[i] < 0 Then Inc (k2);
...
Фрагмент программы 2:
Var i,k1,k2,n:Integer; A:Array[1..30] Of Integer;
Begin
...
k1:=0; {k1 – количество положительных элементов}
k2:=0; {k2 – количество отрицательных элементов}
For i:=1 To n Do Begin
K1:= k1 + ord( A[i] > 0);
K2:= k2 + ord( A[i] < 0);
End;
...
Фрагмент программы 3:
Var i,n:Integer; A:Array[1..30] Of Integer;
Flags:array[Boolean] of byte;
Begin
...
Flags[False]:=0; {количество положительных элементов}
Flags[true]:=0;
{количество отрицательных элементов}
For i:=1 To n Do
Flags[A[i] <= 0]:=Flags[A[i] <= 0]+1–ord(A[i]=0);
Пример 11.14. Дан линейный массив целых чисел. Подсчитать, сколько
в нем различных чисел.
Идея решения: заводим вспомогательный массив, элементами
которого являются логические величины (False – если элемент
уже
встречался ранее, True – иначе).
Var I, N, K, Kol:Integer;
A:Array [1..50] Of Integer; {исходный массив}
L:Array [1..50] Of Boolean; {вспомогательный массив}
Begin
Write('Введите количество элементов массива: ');
ReadLn(N);
For I := 1 To N Do
Begin
Write('A[', I, ']='); ReadLn (A[I]);
L[I]
значениями True}
End;
:=
True;
{Заполняем
вспомогательный
массив
Kol := 0; {переменная, в которой будет храниться значение
количества различных чисел}
For I := 1 To N Do
IF L[I] Then
Begin
Kol := Kol + 1;
FOR K := I+1 TO N DO
{Во
вспомогательный
массив
заносим
значение
False,
если
число уже встречалось ранее или совпадает с текущим элементом
A[I]}
L[K] := (A[K] <> A[I]) And L[K];
End;
WriteLn('Количество различных чисел: ', Kol)
End.
Задание.
Удаление элементов одномерного массива
Пример 11.15. Удалить из массива элемент, значение которого равно
максимуму среди всех элементов массива. Считаем, что все элементы
разные.
Для решения задачи необходимо:
1)
найти номер максимального элемента – k;
2)
сдвинуть все элементы, начиная с k-го на один элемент влево;
3)
последнему элементу присвоить значение 0.
Пусть дан одномерный массив из 6 элементов: 6, 3, 4, 11, 7, 2.
Номер максимального элемента равен 4 (k=4). Т.е., начиная с 4-го
элемента надо сдвигать элементы на один элемент влево: 4-му элементу
присвоить значение 5-го, 5-му – значение 6-го. На этом сдвиг заканчивается.
Таблица 2. Удаление максимального значения
Индекс
1
2
3
4
5
6
Массив до удаления значения
6
3
4
11
7
2
Массив после удаления значения
6
3
4
7
2
0
Таким образом, сдвиг начинается с k-го элемента и идет по (n-1) -й (где
n – количество элементов в массиве). При удалении элемента размерность
массива не изменяется. Обычно последнему элементу (элементу с номером n)
присваивают значение, равное 0. Окончательно массив будет иметь вид: 6, 3,
4, 7, 2, 0.
Программа:
Program delete1;
Const n=6;
Type Tarray= Array[1..n] Of Integer;
Var A:Tarray;
i: Integer; {параметр цикла для перебора элементов}
k: Integer; {номер максимального элемента};
Begin
{Ввод массива А}
...
{Вывод заполненного массива А}
...
{Поиск индекса максимального элемента массива – k}
...
{Удаление элемента с номером k}
For i:= k To n-1 Do
A[i] := A[i+1];
A[n] := 0; {Последний элемент равен 0}
{Вывод нового массива А}
For i:=1 To n-1 Do
Write (A[i]:6);
End.
Пример 11.16. Удалить из массива значения максимальных элементов.
Максимальный элемент может встречаться несколько раз.
Когда необходимо удалять несколько элементов, то это лучше всего
делать с конца массива, т.к. иначе надо снова возвращаться к элементу с
номером, который только что удаляли (это возникает тогда, когда подряд
идут два максимальных элемента: первый удалили, а на его место
становится снова максимальный элемент). Номер максимального элемента
запоминать не будем, а будем, просматривая массив с конца, анализировать
очередной элемент, и если элемент имеет максимальное значение, то
удалим его, при этом значение счетчика удаленных элементов увеличим на 1.
Program delete2;
Const n=6; {количество элементов}
Type Tarray= Array[1..n] Of Integer;
Var A:Tarray;
i,j,kol,zMax: Integer;;
Begin
{Заполнение массива А}
...
{Поиск значения максимального элемента – zMax}
...
{Удаление максимальных элементов}
kol:=0; {количество удаленных элементов}
For i := n DownTo 1 Do
If A[i] = zMax Then
Begin
For j:= i To n-kol-1 Do
A[j] := A[j+1];
A[n-kol] := 0; {Последний элемент равен 0}
Inc(kol); {Увеличение количества
удаленных элементов}
End;
{Вывод нового массива А}
For i:=1 To n-kol Do
Write (A[i],’ ‘);
ReadLn;
End.
Пусть дан одномерный массив из 6 элементов: 6, 11, 4, 11,7, 2.
Пошаговое выполнение программы показано в таблице 4.2.
Таблица 3. Трассировочная таблица удаления нескольких элементов массива
i
A[i]
Max
Массив А
Поиск максимального элемента
1
6 > –32 768, да
*6
2
11>6, да
*11
3
4 >11, нет
11
4
11>11, нет
11
5
7>11, нет
11
6
2>11, нет
11
6, 11, 4, 11,7, 2
Удаление нескольких элементов массива
Массив А
i
A[i]=max
Max
6
2=11, нет
11
5
7=11, нет
6, 11, 4, 11,7, 2
4
11=11, да
6, 11, 4, 7, 2, 0
3
4=11, нет
6, 11, 4, 7, 2, 0
2
11=11, да
6, 4, 7, 2, 0, 0
1
6=11, нет
6, 4, 7, 2, 0, 0
6, 11, 4, 11,7, 2
Задание. Программа в Пример 11.17 имеет сложность – порядка n2.
Напишите программу для решения поставленной задачи, чтобы она имела
линейную сложность порядка n.
Вставка элементов в одномерный массив
Вставлять элемент можно до или после данного элемента, номер этого
элемента можно вводить с клавиатуры или искать при определенных
условиях.
Пример 11.17. Вставить число 100 после 5-го элемента массива.
Элементы исходного массива теряться не должны.
Пусть k – это номер элемента, после которого надо вставить
элемент x (k и x будем вводить с клавиатуры). Тогда вставка
осуществляется следующим образом:
1)
первые k элементов массива остаются без изменений;
2)
все элементы, начиная с (k+1)–го надо сдвинуть на один элемент
вправо;
3)
на место (k+1)-го элемента записываем x, т.е. после k-го элемента
массива.
Пусть дан одномерный массив из 6 элементов: 6, 3, 4, 11, 7, 2. Надо
вставить элемент 100 после пятого элемента массива: 6, 3, 4, 11, 7, 100, 2.
В массиве будет 7 элементов, т.е. массив надо определять на n+1 элемент.
Сдвиг элементов надо проводить с последнего.
Program insert1;
Const n=6; {количество элементов массива}
Var A:Array[1..n+1] Of Integer; i: Integer;
k: Integer; {номер элемента, после которого вставляем элемент
х}
x: Integer; {Вставляемый элемент}
Begin
{Заполнение массива А с клавиатуры}
For i:=1 To n Do
Read (A[i]);
{Ввод номера элемента и значения вставляемого элемента}
WriteLn
(‘Введите
номер
элемента,
после
вставлять’);
WriteLn (‘и вставляемое число’);
ReadLn (k, x);
{Сдвиг элементов массива, начиная с конца}
For i := n DownTo k+1 Do
A[i+1] := A[i];
{Вставка элемента на место (k+1)-го, т.е. после k-го}
A[k+1]:= x;
{Вывод нового массива А}
For i:=1 To n+1 Do
Write (A[i]:6);
End.
которого
Пример 11.18. Вставить число 100 перед 5-м элементом массива.
Задача отличается от предыдущей тем, что в первой сдвигали все
элементы, стоящие после k-го, т.е. с (k+1)-го, а на его место записывали
новый элемент. В данной задаче сдвигаем все элементы с k-го, а затем на его
место записываем новый.
Фрагмент программы:
...
{Сдвиг элементов массива, начиная с конца}
For i := n DownTo k Do
A[i+1] := A[i];
{Вставка элемента на место (k+1)-го, т.е. после k-го}
A[k]:= x;
...
Пример 11.19. Вставить по одному элементу после всех элементов с
заданными свойствами. Например, вставить число после всех элементов
массива, кратных 3.
Размерность массива в результате решения задачи может увеличиться в
два раза, т.к. может оказаться, что вставлять заданное значение придется
после каждого элемента массива.
Если будем просматривать элементы массива с начала и вставлять
новый после элемента с заданными свойствами, то номер последнего
элемента может каждый раз меняться, кроме того, будет просматриваться и
новый (вставленный) элемент и его необходимо будет пропускать
(«перепрыгивать»), поэтому решение будет не эффективным.
Лучше
всего
просматривать
массив,
начиная
с
конца,
тогда
вставляемый элемент «мешать» не будет. Кроме того, номер последнего
элемента можно будет знать (если знать, сколько элементов вставлено на
данный момент), при этом просмотр будет последовательным от n-го до
первого.
Программа:
Program insert2;
Const n=6;
Var A:Array[1..2*n] Of Integer; i, j: Integer;
k: Integer; {Количество вставляемых элементов}
x: Integer; {Вставляемое число}
Begin
{Заполнение массива А с клавиатуры}
For i:=1 To n Do Begin
Write(i, ‘-ый элемент: ’); ReadLn (A[i]);
End;
{Вывод заполненного массива А}
WriteLn( ‘Массив: ’);
For i:=1 To n Do
Write (A[i]:6);
{Ввод значения вставляемого элемента}
WriteLn (‘Введите вставляемое число’);
ReadLn (x);
k:=0;
{Просмотр элементов массива, начиная с конца}
For i := n DownTo 1 Do
If A[i] mod 3 = 0 Then
Begin
{Сдвиг элементов массива, начиная с конца}
For j := n+k DownTo i+1 Do
A[j+1] := A[j];
{Вставка элемента на место (i+1)-го, т.е. после i-го}
A[i+1]:= x;
Inc(k);
End;
{Вывод нового массива А}
For i:=1 To n+k Do
Write (A[i]:6);
End.
Перестановка элементов одномерного массива
Пример 11.20. Ввести одномерный массив и поменять местами
элементы с номерами k и m.
Program replace;
Var mas:Array[1..20] Of Integer;
a,k,m,N,i:Byte;
Begin
ReadLn(N);
For i:=1 To N Do {ввод элементов массива}
Read(mas[i]);
ReadLn(k);
{ввод индексов переставляемых элементов}
ReadLn(m);
a:=mas[k];
{перестановка элементов массива с использованием
дополнительной переменной а}
mas[k]:=mas[m];
mas[m]:=a;
For i:=1 To N Do {вывод элементов массива}
write(mas[i]:6)
End.
Задача о перестановке элементов с заданными свойствами сводится к
этой задаче – надо найти только их номера. Например, чтобы поменять
местами максимальный и минимальный элементы, надо предварительно
определить индексы искомых элементов.
Двумерные массивы
Многомерный массив – это одномерный массив, каждый элемент
которого тоже является массивом. Если каждый элемент массива является
одномерным
массивом,
то
получим
двумерный
массив
(матрицу).
Двумерные массивы используются для хранения таблиц, состоящих из
нескольких строк.
Например, матрицу можно использовать для хранения средних
температур по месяцам в течение нескольких лет (см. таблицу 4.3).
Таблица 4. Пример таблицы, состоящей из нескольких строк.
год
1
2
3
1991
-19
-15
-10
1992
-21
4
5
6
7
8
9
10
11
12
…
2000
-23
Способы описания двумерных массивов
1) Двумерный массив можно описать как одномерный, элементами
которого являются одномерные массивы:
Type Month=Array[1..12] Of Real; {одномерный массив из 12
элементов}
Year=Array[1991..2000] Of Month;
Var T:Year; {двумерный массив из 10 строк, в каждой - 12
элементов}
2) Описание массива T можно сократить:
Type
Year=Array[1991..2000] Of Array[1..12] Of Real;
Var T:Year; {двумерный массив из 10 строк, в каждой - 12
элементов}
3) Еще более краткий способ описания массива из 10 строк и 12
столбцов:
Var T: Аrray[1991..2000,1..12] Of Real;
4) При инициализации двумерных массивов в разделе констант каждая
строка заключается в дополнительную пару круглых скобок:
Сonst
mas:Array[1..3,1..4]
Of
Integer
=((2,3,1,0),
(1,9,1,3), (3,5,7,0));
Описание mas задает матрицу, состоящую из трех строк и четырех
столбцов:
2 3 1 0
1 9 1 3.
3 5 7 0
Положение
элемента
в
двумерном
массиве
описывается
двумя
индексами: первый – номер строки, второй – номер столбца.
Для обращения к отдельному элементу двумерного массива потребуется
два индекса: номер строки и номер столбца: T[1992,3] или T[1992][3].
Организация ввода и вывода информации в двумерных
массивах
Для организации ввода-вывода в двумерных массивах используются
вложенные циклы. Для формирования массива используются все способы из
одномерных массивов. Возможно формирование массива с использованием
датчика случайных чисел и путем ввода с клавиатуры или из файла. Вывод
возможен как на экран, так и в существующий или в новый файл.
Пример 11.21. Ввод и вывод матрицы.
For i:=1991 To 2000 Do
{Внешний цикл (цикл по i) определяет
изменение индекса строк}
For j:=1 To 12 Do
{Внутренний
Read(t[i,j]);
цикл
(цикл
по
j)
определяет изменение номера элемента
в строке – индекс столбцов}
For i:=1991 To 2000 Do
{Вывод матрицы}
Begin
For j:=1 To 12 Do
Write(t[i,j]:8:2,’ ‘);
WriteLn
End;
Пример 11.22. Заполнить матрицу порядка n по следующему образцу:
1
2
3
...
n-2
n-1
n
2
1
2
...
n-3
n-2
n-1
3
2
1
...
n-4
n-3
n-2
...
...
...
...
...
...
...
n-1
n-2
n-3
...
2
1
2
n
n-1
n-2
...
3
2
1
Программа:
Program Matrica;
Var I, J, K, N : Integer; A : Array [1..10, 1..10] Of
Integer;
Begin
Write('Введите размерность матрицы: '); ReadLn(N);
For I := 1 To N Do
{заполнение матрицы}
For J := I To N Do
Begin
A[I, J] := J - I + 1;
A[J, I] := A[I, J];
End;
For I := 1 To N Do
{вывод матрицы}
Begin
WriteLn;
For J := 1 To N Do Write(A[I, J]:4);
End
End.
Основные свойства квадратных матриц
Если количество строк и столбцов в двумерном массиве одинаковое, то
такой массив называется квадратным. Например, при n=3:
a11
a12
a13
a21
a22
a23
a31
a32
a33
1. Квадратные матрицы имеют главную и побочные диагонали.
Например, для матрицы А на главной диагонали лежат элементы 1, 5 и 9, а на
побочной – 3, 5 и 7.
 1 2 3


A   4 5 6
7 8 9


Если:
i=j – элементы расположены на главной диагонали;
i>j – элементы расположены ниже главной диагонали;
i<j – элементы расположены выше главной диагонали;
i+j-1=n – элементы расположены на побочной диагонали. Элемент
матрицы на побочной диагонали в общем виде будет иметь адрес A[i,N+1–
i];
i+j-1<n – элементы расположены над побочной диагональю;
i+j-1>n – элементы расположены под побочной диагональю.
2. Квадратная матрица, у которой все элементы, исключая элементы
главной диагонали, равны нулю, называется диагональной матрицей:
1 0 0


A  0 5 0 .
0 0 9


3. Диагональная матрица, у которой все элементы, стоящие на главной
диагонали, равны 1, называется единичной матрицей.
4. Если в матрице A(n,m) поменять местами строки и столбцы, то
получится матрица AT(n,m), которая называется транспонированной
матрицей:

a
 11
T
A   a12
 ...

 a1m


a
a 12 ... a 1m 
 11

A   a 21 a 22 ... a 2 m 
 ...



 a n1 a n 2 ... a nm 

a21... an1 

a22 ... an 2  .


a2 m ... anm 
Типовые задачи обработки двумерных массивов
Программы
большинства
матричных
задач
строятся
на
основе
вложенных циклов. Обычно внешний цикл работает по строкам матрицы, а
внутренний цикл – по столбцам матрицы.
Задачи, использующие двумерные массивы:
1)
сумма
элементов
(всех
или
удовлетворяющих
заданному
условию);
2)
нахождение количества элементов с заданными свойствами;
3)
определить,
отвечает
ли
заданный
массив
некоторым
требованиям (существует ли элемент, равный 0);
Основные действия, которые можно выполнять над матрицами
1)
суммировать;
2)
находить разность;
3)
произведение матрицы на некоторое число;
4)
произведение двух матриц.
Пример 11.23. Ввести целочисленный массив размерности NхN из
файла и вывести на экран сам массив и сумму всех его элементов.
Program summa;
Const Nmax=50;
Type mas=Array[1..Nmax,1..Nmax] Of Integer;
Var a:mas; i,j,sum,N:Integer; f:text;
Begin
assign(f,’f.dat’);
reset(f);
ReadLn(N);
{Ввод размерности массива}
{Ввод элементов и суммирование}
sum:=0;
For i:=1 To N Do
For j:=1 To N Do
Begin
Read(f,a[i,j]);
sum:=sum+a[i,j];
End;
Close(f)
{Вывод элементов массива}
WriteLn(‘Массив’);
For i:=1 To N Do
Begin
For j:=1 To N Do
Write(a[i,j]);
WriteLn
End;
{Вывод суммы элементов массива}
Writeln(‘Сумма=’,sum);
End.
Пример 11.24. В матрице размерностью 10х10 поменять местами
столбцы с номерами k и n. Значения элементов массива вводятся из файла
f.dat.
Program replace_matr;
Type mas=Array[1..10,1..10] Of Integer;
Var a:mas;
k,n,j,i,b:Integer;
f:Text;
Begin
ReadLn(k); {ввод номеров столбцов}
ReadLn(n);
{Ввод элементов из файла}
Assign(f,’f.dat’);
Reset(f);
for i:=1 to 10 do
for j:=1 to 10 do
Read(f,a[i,j]);
Close(f)
{Столбцы с номерами k и n меняются местами}
for i:=1 to 10 do
begin
b:=a[i,k];
a[i,k]:=a[i,n];
a[i,n]:=b
end;
{Вывод элементов матрицы}
For i:=1 to 10 do
Begin
For j:=1 to 10 do
Write(a[i,j]);
WriteLn
End;
End.
Пример 11.25. В матрице размерностью NхN (N вводится с
клавиатуры) найти сумму элементов, стоящих выше главной диагонали.
Матрица заполняется случайными числами в диапазоне от 1 до 100..
Const NMax=10;
Var A : Array[1..NMax,1..NMax] Of Integer;
I, K : Byte; S : Integer;
Begin
Write(‘N=’); ReadLn(N);
Randomize;
S:=0;
{заполнение и вывод матрицы; вычисление суммы элементов выше
главной диагонали}
For I:=1 To N Do
Begin
For K:=1 To N Do
Begin
A[I,K]:=Random(101)+1;
Write(A[I,K]:6);
If K>I Then S:=S+A[I,K]
End;
Writeln
End;
Writeln('Сумма элементов выше главной диагонали равна ',S)
End.
Другой способ решения задачи. Ввод и вывод элементов матрицы
выполнить в начале программы, а нахождение искомой суммы реализовать
следующим образом:
...
S:=0;
For I:=1 To N Do
For K:=I+1 To N Do
S:=S+A[I,K];
...
Пример 11.26. Дана целочисленная квадратная матрица. Найти в
каждой строке наибольший элемент и поменять его местами с элементом
главной диагонали.
Program Obmen;
Var N, I, J, Max,Ind, Vsp : Integer;A : Array [1..15, 1..15]
Of Integer;
Begin
WRITE('Введите количество элементов в массиве: ');
READLN(N);
FOR I := 1 TO N DO
FOR J := 1 TO N DO
Begin
WRITE('A[', I, ',', J, '] '); READLN(A[I, J])
End;
FOR I := 1 TO N DO Begin
Max := A[I, 1]; Ind := 1;
FOR J := 2 TO N DO
IF A[I, J] > Max THEN
Begin
Max := A[I, J]; Ind := J
End;
Vsp := A[I, I]; A[I, I] := A[I, Ind]; A[I, Ind] := Vsp
End;
FOR I := 1 TO N DO Begin
FOR J := 1 TO N Do Write(A[I, J] : 6);
WriteLn;
End;
End.
Для работы с двумерными массивами желательно подготовить
программу-шаблон, которая включает ввод данных из файла и вывод
элементов двумерного массива на экран (можно в файл). Размеры
двумерного массива можно также вводить из файла.
Задание. Матрица смежности – типа найти расстояние
Действия над массивами как единым целым
Единственное действие, которое можно выполнять над массивами
целиком, но только при условии, что массивы описание массивов полностью
совпадает, – это присваивание.
Пример 11.27. Выполнение операции присваивания массивов.
1) Var p,q:Array[1..15,1..10] Of Real;
...
p:=q;
...
В этом случае все элементы массива p станут равными элементам
массива q.
2) Type vec=Array[1..10] Of real;
Var p:Array[1..15] Of vec;
q:Array [1..15,1..10] Of real;
...
p:=q;
...
В данном случае будет выдана ошибка несоответствия типов, так как
описание массивов не совпадает, несмотря на то, что размеры и базовые
типы массивов совпадают.
Download