- •4. Организация программ со структурой вложенных циклов
- •4. Организация программ со структурой вложенных циклов
- •; // Конец второго внутреннего цикла
- •//Вычисление и печать таблицы умножения чисел от 1 до 100
- •Write(I*j); // умножение выполняется 10000 раз
- •Begin begin
- •WriteLn(s:7:2); WriteLn(s:7:2);
- •Вычисление определенного интеграла с заданной точностью
- •Пример программы вычисления определенного интеграла с точностью методом трапеций
- •Задания 4.1 на вычисление интеграла с точностью.
- •Вычисление наибольшего (наименьшего) значения функции с заданной точностью на заданном интервале
- •// Числения максимума
- •// Тервала
- •Задания 4.2 на нахождение экстремума функции с заданной точностью.
- •Обработка матриц
- •Менее предпочтительными, но допустимыми будут объявления типа
- •X:array[1.. MMax, 1..NMax] of Real;
- •X:array[1..12, 1..14] of Real;
- •Пример 1 выполнения задания на матрицы
- •Пример 2 выполнения задания на матрицы
- •Пример 3 выполнения задания на матрицы
- •Пример 4 выполнения задания на матрицы
- •Задания 4.3 на обработку матриц (вложенные циклы)
Обработка матриц
Матрицы представляют собой один из наиболее удобных математических объектов, обработка которого ведет к необходимости программирования вложенных циклов. При программной реализации обработки матриц будем использовать двумерные массивы (элементы которых имеют два индекса), считая, что элементы Хij матрицы Х, i=1, 2,...,m, j=1, 2,…,n размещаются в ячейках соответствующего массива с такими же индексами. Это позволит сделать текст программы удобным для понимания процесса обработки и уменьшить, в некоторых случаях, объём вычислений. Соответственно первый индекс массива будем называть номером строки, а второй – номером столбца.
Имея в виду соответствие элементов матрицы элементам массива, им дают, как правило, одинаковые имена; иногда в пояснениях к программе вместо термина «массив» будем использовать термин «матрица», как бы отождествлять объекты предметной области с объектами программы для лучшего понимания процессов обработки.
При постановке задач на обработку матриц с целью обеспечения применимости программ для обработки матриц, например, матрицы Х, размеры которых не должны превосходить заданных значений, например, m12 и n14, будем использовать сокращенное обозначение, например, Х(m,n), m12, n14. Указанные в таком обозначении максимальные значения индексов матрицы будут использоваться в объявлении типа соответствующего двумерного массива, а сами эти максимальные значения индексов желательно объявить в виде именованных констант. Если также учесть, что двумерный массив можно рассматривать и объявлять как одномерный массив с базовым типом массив, то объявление типа массива для хранения матриц с размерами, не превышающими 12х14 будет следующим.
const
mMax=12; nMax=14;
type
//объявление типа строки двумерного массива типа tM
tV=array[1..mMax] of Real;
//объявление типа двумерного массива
tM=array[1..nMax] of tV;
(при описании типа двумерного массива необходимо задавать тип обоих индексов и тип самих элементов матрицы).
Такое двухэтапное объявление типа двумерного массива удобно тем, что строка массива будет совместима по присваиванию с одномерным массивом того же типа tV.
Задание в разделе констант максимальных значений для количества строк и столбцов улучшает стиль программирования, так как в случае необходимости изменения количества строк или столбцов программисту не придется внимательно изучать весь текст программы, а достаточно будет изменить значения соответствующих констант.
Переменная-двумерный массив объявляется в разделе объявления переменных
var
X:tM;
Менее предпочтительными, но допустимыми будут объявления типа
tM=array[1..mMax, 1..nMax] of Real;
или
tM=array[1..12, 1..14] of Real;
и объявление массива одной строкой
var
X:array[1.. MMax, 1..NMax] of Real;
или
X:array[1..12, 1..14] of Real;
Последние варианты оказывается менее предпочтительны, так как при использовании в подпрограммах типизированных параметров, представляющих матрицы и векторы, без предварительного описания используемых типов обойтись невозможно.
При работе с матрицами надо помнить, что первый индекс соответствует номеру строки, а второй индекс – номеру столбца.
Ввод-вывод матриц можно осуществить только с использованием вложенного цикла. Обычно принято вводить матрицу в виде матрицы, т.е. по строкам как это принято делать на бумаге. В этом случае во внутреннем цикле должен обеспечиваться ввод (вывод) одной строки матрицы. Внешний цикл будет задавать ввод (вывод) строк матрицы и переход в начало новой строки после ввода (вывода) очередной строки.
Фрагмент программы, обеспечивающей ввод и вывод матрицы Х(m,n), m12, n14, ранее описанной, имеет следующий вид:
WriteLn(‘Введите количество строк и столбцов матрицы’);
ReadLn(M,N);
WriteLn(‘Введите элементы матрицы по строкам’);
for I:=1 to M do //цикл ввода всех строк матрицы
begin
for J:=1 to N do // цикл ввода очередной строки матрицы
Read(X[I,J]);
ReadLn; //переход в начало новой строки файла ввода
end;
WriteLn(‘Введенная матрица’);
for I:=1 to M do //цикл вывода всех строк матрицы
begin
for J:=1 to N do // цикл вывода очередной строки матрицы
Write(X[I,J]:6:1,’ ‘);
WriteLn; //переход в начало новой строки файла вывода
end;
Порядок расположения циклов при вводе/выводе имеет существенное значение. Если поменять местами заголовки циклов, то вводимые значения будут присваиваться элементам столбца, а не элементам строки. При выводе матрицы в этом случае будет выведена фактически транспонированная матрица
Также надо соблюдать аккуратность при использовании приемов программирования. Например, при вычислении сумм и произведений надо следить за тем, в каком месте программы присваиваются начальные значения соответствующим переменным.
Следующий фрагмент программы позволяет вычислить сумму и произведение всех элементов матрицы:
S:=0; Pr:=1;
for I:=1 to M do
for J:=1 to N do
begin
S:=S+A[I,J];
Pr:=Pr*A[I,J];
end;
WriteLn(‘s=’,S:8:2,’ pr=’,Pr:8:2);
При изменении места расположения операторов присваивания S:=0; Pr:=1; смысл вычислений меняется:
for I:=1 to M do
begin
S:=0; Pr:=1;
for J:=1 to N do
begin
S:=S+A[I,J];
Pr:=Pr*A[I,J];
end;
WriteLn(‘s=’,S:8:2,’ pr=’,Pr:8:2);
end;
Приведенный фрагмент программы позволит вычислить сумму и произведение элементов каждой строки матрицы, а не всех элементов матрицы.
При вычислении максимального и минимального элементов матрицы также надо правильно устанавливать начальные значения вычисляемых переменных, а также правильно задавать пределы изменения параметров циклов:
Amax:=A[1,1]; Imax:=1; Jmax:=1;
Amin:=A[1,1]; Imin:=1; Jmin:=1;
for I:=1 to M do
for J:=1 to N do
if A[I,J]>Amax then
begin
Amax:=A[I,J]; Imax:=I; Jmax:=J;
end
else if A[I,J]<Amin then
begin
Amin:=A[I,J]; Imin:=I; Jmin:=J;
end;
WriteLn(‘amax=’,Amax:8:2,’ imax=’,Imax:2
,’ jmax=’,Jmax:2,’ amin=’,Amin:8:2
,’ imin=’,Imin:2,’ jmin=’,Jmin:2,);
В приведенном фрагменте программы нельзя опускать операторы присваивания начальных значений индексам минимального и максимального элементов (Imax:=1; Jmax:=1; Imin:=1; Jmin:=1;). В случае отсутствия указанных операторов индексы искомых элементов будут не определены в том случае, если первый элемент A[1,1] является максимальным (минимальным).
При поиске минимального (максимального) элемента матрицы нельзя устанавливать начальное значение параметра цикла, равное двум, как это можно сделать при обработке одномерного массива. Следующий фрагмент программы будет приводить к неверному результату, так как будут исключены из рассмотрения все элементы первой строки, за исключением первого, значение которого выбирается в качестве начального значения для максимума и минимума.
Amax:=A[1,1]; Imax:=1; Jmax:=1;
Amin:=A[1,1]; Imin:=1; Jmin:=1;
for I:=2 to M do
for J:=1 to N do
.....................
Рассмотрим примеры обработки матриц.
