Компания ALT Linux
Опубликован: 10.04.2015 | Доступ: свободный | Студентов: 762 / 0 | Длительность: 14:03:00
Специальности: Программист, Преподаватель
Лекция 6:

Обработка матриц в Паскале

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

6.2 Алгоритмы и программы работы с матрицами

Рассмотри несколько примеров решения задач обработки матриц.

ЗАДАЧА 6.3. Найти сумму элементов матрицы, лежащих выше главной диагонали (см. рис. 6.13).
Рисунок к задаче 6.3

Рис. 6.13. Рисунок к задаче 6.3

Рассмотрим два алгоритма решения данной задачи.

Первый алгоритм решения данной задачи (см. рис. 6.14) построен следующим образом. Вначале переменная S для накапливания суммы обнуляется (S:=0). Затем с помощью двух циклов (первый по строкам, второй по столбцам) перебираются все элементы матрицы, но накапливание суммы происходит только в том случае, если этот элемент находится выше главной диагонали (если выполняется свойство i<j).

Текст консольного приложения с комментариями приведён ниже.

var
a : array [ 1.. 15, 1.. 10 ] of real;
i, j, n,m: integer; s : real;
begin
writeln ( ’введите размеры матрицы ’ );
writeln ( ’ n - количество строк,  m - количество столбцов ’ );
readln ( n,m);
writeln ( ’Введите матрицу A ’ );
for i :=1 to n do
for j :=1 to m do
read ( a [ i, j ] );
s : = 0;
for i :=1 to n do
for j :=1 to m do
if j>i then {Если элемент лежит выше главной диагонали, то}
s := s+a [ i, j ]; {наращиваем сумму.}
writeln ( ’матрица А ’ );
for i :=1 to n do
begin
for j :=1 to m do
{Здесь важен формат, особенно общая ширина поля!}
write ( a [ i, j ] : 8 : 3, ’   ’ );
writeln
end;
writeln ( ’сумма элементов  матрицы ’, s : 8 : 3 );
end.
Блок-схема задачи 6.3 (алгоритм 1)

Рис. 6.14. Блок-схема задачи 6.3 (алгоритм 1)
Блок-схема задачи 6.3 (алгоритм 2)

Рис. 6.15. Блок-схема задачи 6.3 (алгоритм 2)

Результаты работы программы представлены на рис. 6.16.

Второй алгоритм решения этой задачи представлен на рис. 6.15.

В нём проверка условия i<j не выполняется, но, тем не менее, в нём также суммируются элементы матрицы, находящиеся выше главной диагонали. Для пояснения функционирования алгоритма обратимся к рисунку 6.13. В первой строке заданной матрицы необходимо сложить все элементы, начиная со второго. Во второй — все, начиная с третьего, в i–й строке процесс суммирования начнётся с (i+1)-го элемента и так далее. Таким образом, первый цикл работает от 1 до N, а второй от i+1 до M.

Предлагаем читателю самостоятельно составить программу, соответствующую описанному алгоритму.

Результаты работы программы решения задачи 6.3

Рис. 6.16. Результаты работы программы решения задачи 6.3
ЗАДАЧА 6.4. Вычислить количество положительных элементов квадратной матрицы A, расположенных по её периметру и на диагоналях.
Рисунок к условию задачи 6.4

Рис. 6.17. Рисунок к условию задачи 6.4

В квадратной матрице число строк равно числу столбцов. Прежде чем приступить к решению задачи, рассмотрим рисунок 6.17, на котором изображена схема диагоналей квадратных матриц различной размерности.

Из рисунка видно, что нет необходимости рассматривать все элементы матрицы. Достаточно рассмотреть элементы, расположенные в первой и последней строках, в первом и последнем столбцах, а также на диагоналях квадратной матрицы. Все эти элементы отмечены на рис. 6.17, причём чёрным цветом выделены элементы, которые принадлежат строкам, столбцам и диагоналям. Например, элемент A_{1,1} принадлежит первой строке, первому столбцу, и главной диагонали матрицы, элемент A_{N,N} находится в последней строке, последнем столбце и принадлежит главной диагонали. Кроме того, если N — число нечётное (на рисунке 6.17 эта матрица расположена слева), то существует элемент с индексом (N div 2 + 1, N div 2 + 1), который находится на пересечении главной и побочной диагоналей. При чётном значении N (матрица справа на рис. 6.17) диагонали не пересекаются.

Рассмотрим алгоритм решения задачи. Для обращения к элементам главной диагонали вспомним, что номера строк этих элементов всегда равны номерам столбцов. Поэтому если параметр i изменяется циклически от 1 до N, то A_{i,i} — элемент главной диагонали. Воспользовавшись свойством, характерным для элементов побочной диагонали, получим: i+j -1 = N \to j = N - i+1, следовательно, для строк i=1,2,...,N элемент A_{i,N-i+1} — элемент побочной диагонали. Элементы, находящиеся по периметру матрицы записываются следующим образом: A_{1,i} — элементы, расположенные в первой строке (i=1,2,...,N), A_{N,i} — элементы, расположенные в последней строке (i=1,2,...,N) и, соответственно, A_{i,1} — элементы, расположенные в первом столбце (i=1,2,...,N), A_{i,N} — в последнем столбце (i=1,2,...,N).

Алгоритм обработки построим следующим образом: сначала обработаем элементы, расположенные на диагоналях квадратной матрицы. Для этого необходимо в каждой строке (i=1,2,...,N) проверять знак элементов A_{i,i} и A_{i,N-i+1}.

for i :=1 to N do
	begin
		if ( a [ i, i ] >0) then k:=k+1;
		if a [ i,N - i +1]>0 then k:=k+1;
	end;

Так как угловые элементы матрицы уже учтены при проверке диагональных элементов, при обработке элементов, расположенных по периметру матрицы, их учитывать уже не нужно. Поэтому надо перебрать элементы со второго до предпоследнего в первой и последней строке, в первом и последнем столбце.

for i :=2 to N - 1 do
	begin
{Если элемент находится в первой строке.}
	if ( a [ 1, i ] >0) then k:=k+1;
{Если элемент находится в последней строке.}
	if ( a [N, i ] >0) then k:=k+1;
{Если элемент находится в первом столбце.}
	if ( a [ i,1] >0) then k:=k+1;
{Если элемент находится в последнем столбце.}
	if ( a [ i,N] >0) then k:=k+1;
end;

Затем нужно проверить, не был ли элемент, находящийся на пересечении диагоналей, подсчитан дважды. Это могло произойти только в том случае, если N — нечётно и элемент, расположенный на пересечении диагоналей4На пересечении диагоналей находится элемент с индексами (N div 2 + 1, N div 2 + 1)., положителен.

if (N mod 2 <> 0) and ( a [ n div 2 + 1, n div 2 + 1 ] > 0) then
k:=k -1;

Ниже приведён полный текст консольного приложения решения задачи 6.4 с комментариями.

var a : array [ 1.. 10, 1.. 10 ] of integer;
	i, j, N, k : integer;
begin
	write ( ’N= ’ );
	readln (N);
//Ввод исходной матрицы.
	writeln ( ’Введите матрицу A ’ );
	for i :=1 to N do
		for j :=1 to N do
			read ( a [ i, j ] );
//Вывод исходной матрицы.
	writeln ( ’Была введена матрица A: ’ );
	for i :=1 to N do
	begin
		for j :=1 to N do
			write ( a [ i, j ], ’   ’ );
		writeln;
	end;
	k : = 0;
//Обработка элементов, расположенных на диагоналях матрицы.
	for i :=1 to N do
	begin
		if ( a [ i, i ] >0) then k:=k+1;
		if a [ i,N-i +1]>0 then k:=k+1;
end;
//Обработка элементов, расположенных по периметру матрицы.
	for i :=2 to N - 1 do
	begin
		if ( a [ 1, i ] >0) then k:=k+1;
		if ( a [N, i ] >0) then k:=k+1;
		if ( a [ i,1] >0) then k:=k+1;
		if ( a [ i,N] >0) then k:=k+1;
end;
{Если элемент, находящийся на пересечении диагоналей, подсчитан дважды,}
{то уменьшить вычисленное значение к на один.}
	if ( n mod 2<>0) and ( a [N div 2+1,N div 2+1]>0) then
k:=k _1;
	writeln ( ’ k= ’, k );
end.

На рис. 6.18 представлены результаты работы программы решения задачи 6.4.

Результаты решения задачи 6.5

Рис. 6.18. Результаты решения задачи 6.5
ЗАДАЧА 6.5. Проверить, является ли заданная квадратная матрица единичной.

Единичной называют матрицу, у которой элементы главной диагонали — единицы, а все остальные — нули. Например,

\left(\begin{matrix}
1&0&0&0\\
0&1&0&0\\
0&0&1&0\\
0&0&0&1
\end{matrix}\right)

Решать задачу будем так. Предположим, что матрица единичная (pr:=true) и попытаемся доказать обратное. В двойном цикле по по строкам (i:=1,2,...,N) и по по столбцам (j:=1,2,...,N) перебираем все элементы матрицы. Если диагональный элемент (i = j ) не равен единице или элемент, расположенный вне диагонали (i \not = j), не равен нулю5Воспользовавшись логическими операциями and и or это сложное условие можно записать так: if ((i=j) and (a[i,j]<>1)) or ((i<>j) and (a[i,j]<>0)) then..., то в логическую переменную pr записываем значение false и прекращаем проверку (аварийно покидаем цикл). После цикла проверяем значение pr. Если переменная pr по прежнему равна true, то матрица единичная; в противном случае она таковой не является. Блок-схема алгоритма решения задачи представлена на рис. 6.19.

Блок-схема алгоритма решения задачи 6.5

увеличить изображение
Рис. 6.19. Блок-схема алгоритма решения задачи 6.5
program pr_6_5;
var a : array [ 1.. 10, 1.. 10 ] of real;
	i, j, n : integer;
	pr : boolean;
begin
	writeln ( ’Введите размер матрицы ’ );
	readln ( n );
	writeln ( ’Введите матрицу ’ );
	for i :=1 to n do
		for j :=1 to n do
		read ( a [ i, j ] );
{Предположим, что матрица единичная,}
{и присвоим логической переменной значение "истина".}
{Если значение этой переменной при выходе из цикла не изменится, это}
{будет означать, что матрица действительно единичная.}
	pr := true;
	for i :=1 to n do
		for j :=1 to n do
		if ( ( i=j ) and ( a [ i, j ]<>1)) or ( ( i <>j ) and ( a [ i, j ]<>0))
		  then
{Если элемент лежит на главной диагонали и не равен единице или элемент}
{лежит вне главной диагонали и не равен нулю, то}
begin
{логической переменной присвоить значение "ложь"}
{это будет означать, что матрица единичной не является,}
pr := false;
{выйти из цикла.}
break;
end;
{Проверка значения логической переменной и печать результата.}
if pr then
writeln ( ’Матрица единичная ’ )
else writeln ( ’Матрица не является единичной ’ );
end.
< Лекция 5 || Лекция 6: 123456 || Лекция 7 >
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.