Задача «Три массива»

Постановка задачи. Даны три квадратные матрицы a, b и c разного размера. Какая из матриц имеет наименьшую разность между количествами элементов, больших заданного числа и расположенных выше главной/побочной диагонали? Если наименьшие значения совпадают, вывести соответствующее сообщение. Для каждой из матриц использовать своё заданное значение. Для обработки матриц необходимо использовать две функции (для главной и побочной диагонали), для ввода и вывода матриц – процедуры. Ввод всех данных осуществляется из файла, вывод – в файл. Для передачи имён файлов должны использоваться параметры программы.

Шаг 1. Общая структура программы

Программа на процедурном языке программирования состоит из данных и действий по их обработке. program Lab12; { Описание данных – констант, типов и переменных } begin { Обработка данных } end.

Шаг 2. Разработка структуры данных

Из постановки задачи следует, что на вход программы подаются три матрицы a, b и c. Также должны быть заданы их размеры na, nb и nc (по условию матрицы квадратные, поэтому количество строк и столбцов задаётся одной и той же переменной). Кроме того, надо ввести три числа для сравнения с элементами матриц va, vb и vc.

Из постановки задачи также следует, что в каждой матрице надо найти разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположеных выше побочной диагонали da, db и dc, и сравнить эти значения между собой.

Для задания матрицы введём константу, ограничивающую максимально возможное количество строк и столбцов, и тип для матрицы. program Lab12; const nmax = 10; type matrix = array [1..nmax, 1..nmax] of real; var { Входные данные } a, b, c: matrix; { Исходные матрицы } na, nb, nc: integer; { Количество элементов матриц a, b, c соответственно } va, vb, vc: real; { Значения для сравнения с элементами матриц a, b, c соответственно } { Выходные данные } da, db, dc: integer; { Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a, b, c соответственно } begin { Обработка данных } end.

Шаг 3. Разработка тестов

№ теста Входные данные Ожидаемые результаты Смысл теста
1 na = 3
a: 1 2 3
   4 5 6
   7 8 9
nb = 4
b: 1 2 3 4
   8 7 6 5
   9 8 7 6
   8 9 8 9
nc = 3
с: 3 2 1
   6 5 4
   9 8 7
va = 17
vb = 18
vc = 15
da = db = dc = 0 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, одинакова во всех трёх матрицах.
2 na = 4
a: 1   2   3  -4
   5  -6   7   8
  -9  10 -11  12
 -13  14  15 -16
nb = 4
b: 1  -2   3   4
  -5   6   7   8
   9  10  11  12
 -13  14 -15  16
nc = 4
c: 1   2   3   4
  -5   6   7   8
  -9 -10 -11  12
  13 -14 -15 -16
va = 0
vb = 0
vc = 0
da = db = 1 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a и b одинакова и меньше, чем в матрице c.
3 na = 4
a: 1   2   3  -4
   5  -6   7   8
  -9  10 -11  12
 -13  14  15 -16
nb = 4
b: 1   2   3   4
  -5   6   7   8
  -9 -10 -11  12
  13 -14 -15 -16
nc = 4
c: 1  -2   3   4
  -5   6   7   8
   9  10  11  12
 -13  14 -15  16
va = 0
vb = 0
vc = 0
da = dc = 1 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a и c одинакова и меньше, чем в матрице b.
4 na = 4
a: 1   2   3   4
  -5   6   7   8
  -9 -10 -11  12
  13 -14 -15 -16
nb = 4
b: 1   2   3  -4
   5  -6   7   8
  -9  10 -11  12
 -13  14  15 -16
nc = 4
c: 1  -2   3   4
  -5   6   7   8
   9  10  11  12
 -13  14 -15  16
va = 0
vb = 0
vc = 0
db = dc = 1 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах b и c одинаково и меньше, чем в матрице a.
5 na = 4
a: 0  -7   3  -5
  -1  -9  -7  -3
  -5  13 -13  -1
  13  34  55 -26
nb = 4
b:-5   4   9   8
   1   0  -1   5
 -99  17 -12  -2
 -33  44   5   3
nc = 4
c: 1  -2  -3  -4
  -5   2   0   1
 -11   0   3   5
  -1   9  -3  10
va = -5
vb = -3
vc = -7
da = 0 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрице a меньше, чем в матрицах b и c.
6 na = 4
a: 0  -5   6   4
 -10  -3   0  -1
  -8  14  -3  -1
  -7   8  -5  -2
nb = 3
b: 5   4   9
   1   0  -1
   9   7 -12
nc = 4
c: 7  -8  -3  -5
  32   0  23  41
  -4   2  53  55
  13  77  15  20
va = -2
vb = 0
vc = 3
db = -1 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрице b меньше, чем в матрицах a и c.
7 na = 4
a:-5   5   6   4
 -11 -33  40  71
 -88  19  36  55
  27  48  -4  -3
nb = 4
b:-4   2   1   8
  -5  -9   7   3
  -3   5   0   4
   6   1   3   2
nc = 4
c: 7  -8  -3  -5
 -22 -10   8   9
 -57   6   2   5
  22  -9   2   0
va = -3
vb = -2
vc = -7
dc = 3 Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрице c меньше, чем в матрицах a и b.

Шаг 4. Разработка общей структуры программы

Программа должна состять из трёх основных частей – ввод исходных данных, получение результатов, вывод полученных результатов. program Lab12; const nmax = 10; type matrix = array [1..nmax, 1..nmax] of real; var { Входные данные } a, b, c: matrix; { Исходные матрицы } na, nb, nc: integer; { Количество элементов матриц a, b, c соответственно } va, vb, vc: real; { Значения для сравнения с элементами матриц a, b, c соответственно } { Выходные данные } da, db, dc: integer; { Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a, b, c соответственно } begin { Ввод исходных данных } { Поиск количества элементов, больших заданного числа и расположенных выше главной диагонали, в каждой из трёх матриц } { Поиск количества элементов, больших заданного числа и расположенных выше побочной диагонали, в каждой из трёх матриц } { Вывод результатов } end.

Шаг 5. Разработка ввода и вывода

Организуем ввод из файла и вывод в файл с использованием параметров программы, проверкой правильности передачи параметров и существования входного файла, как уже было сделано в лабораторной работе № 6. Для ввода и вывода матриц будем использовать процедуры. Обратите внимание, что процедуры ввода и вывода расчитаны на прямоугольные матрицы с разным количеством строк и столбцов. Однако, они успешно вводят и выводят квадратные матрицы, в качестве количества строк и столбцов передаётся одна и та же переменная.

В качестве заглушки для обработки данных напишем пока присваивание переменным da, db и dc значение 0. В этом случае программа должна выводить сообщение о равенстве разностей между количествами во всёх трёх матрицах.

Входная форма

Выходная форма

program Lab12; const nmax = 10; type matrix = array [1..nmax, 1..nmax] of real; var { Входные данные } a, b, c: matrix; { Исходные матрицы } na, nb, nc: integer; { Количество элементов матриц a, b, c соответственно } va, vb, vc: real; { Значения для сравнения с элементами матриц a, b, c соответственно } { Выходные данные } da, db, dc: integer; { Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a, b, c соответственно } { Промежуточные данные } f: TextFile; { Файловая переменная } { Процедура ввода матрицы из файла } procedure Get(var x: matrix; var m, n: integer; var f: TextFile); ... { Процедура вывода матрицы в файл } procedure Put(const x: matrix; m, n: integer; name: string; var f: TextFile); ... begin if ParamCount < 2 then { Проверяем количество параметров } writeln('Недостаточно параметров!'); else begin if not FileExists(ParamStr(1)) then { Проверяем существование файла } writeln('Невозможно открыть файл ''', ParamStr(1), ''' для чтения'); else begin { Ввод исходных данных } AssignFile(f, ParamStr(1)); { Открываем файл } Reset(f); Get(a, na, na, f); Get(b, nb, nb, f); Get(c, nc, nc, f); readln(f, va, vb, vc); CloseFile(f); { Закрываем файл } { Поиск разностей между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали } da := 0; db := 0; dc := 0; { Вывод результатов } AssignFile(f, ParamStr(2)); Rewrite(f); Put(a, na, na, 'A', f); writeln(f, 'Заданное значение = ', va:8:2); writeln(f); Put(b, nb, nb, 'B', f); writeln(f, 'Заданное значение = ', vb:8:2); writeln(f); Put(c, nc, nc, 'C', f); writeln(f, 'Заданное значение = ', vc:8:2); writeln(f); if (da = db) and (db = dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, совпадает во всех трёх матрицах и равна ', da:2) else if (da = db) and (da < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах A и B и равна ', da:2) else if (da = dc) and (da < db) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах A и C и равна ', da:2) else if (db = dc) and (db < da) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах B и C и равна ', db:2) else if (da < db) and (da < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице A и равна ', da:2) else if (db < da) and (db < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице B и равна ', db:2) else writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице C и равна ', dc:2); CloseFile(f); end; end; end.

Шаг 6. Разработка вычислительной части программы

Для определения количества элементов, больших заданного числа и расположенных выше главной/побочной диагонали, в каждой матрице будем использовать функции.

Шаг 7. Разработка интерфейса функций

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

Функция, как и любой алгоритм, должна получать данные и содержать действия по их обработке. В качестве исходных данных функция должна получить матрицу и количество её строк и столбцов (одинаковое в данном случае, т.к. функция, обрабатывающая элементы выше главной/побочной диагонали, будет работать только с квадратными матрицами), а также число для сравнения. Результатом будет количество элементов матрицы, больших заданного числа и расположенных выше главной/побочной диагонали. Входные данные функции передаются через параметры, при этом матрицу можно передать как параметр-константу, а количество строк и столбцов и число для сравнения – как параметры-значения. Результат функции передаётся через имя функции или переменную result.

{ Функция поиска количества элементов матрицы, больших заданного числа и расположенных выше главной диагонали } function CountAboveMainDiagonal(const x: matrix; n: integer; v: real): integer; var { Объявления локальных переменных } begin { Операторы } end; { Функция поиска количества элементов матрицы, больших заданного числа и расположенных выше побочной диагонали } function CountAboveSideDiagonal(const x: matrix; n: integer; v: real): integer; var { Объявления локальных переменных } begin { Операторы } end;

Шаг 7. Тестирование интерфейса функций

Вызовем функции в основной программе, передав им нужные фактические параметры. В теле функций напишем пока заглушку, которая будет присваивать результату общее количество элементов матрицы, расположенных выше главной/побочной диагонали.

program Lab12; const nmax = 10; type matrix = array [1..nmax, 1..nmax] of real; var { Входные данные } a, b, c: matrix; { Исходные матрицы } na, nb, nc: integer; { Количество элементов матриц a, b, c соответственно } va, vb, vc: real; { Значения для сравнения с элементами матриц a, b, c соответственно } { Выходные данные } da, db, dc: integer; { Разность между количествами элементов, больших заданного числа, расположенных выше главной диагонали и расположенных выше побочной диагонали, в матрицах a, b, c соответственно } { Промежуточные данные } f: TextFile; { Файловая переменная } { Процедура ввода матрицы из файла } procedure Get(var x: matrix; var m, n: integer; var f: TextFile); ... { Процедура вывода матрицы в файл } procedure Put(const x: matrix; m, n: integer; name: string; var f: TextFile); ... { Функция поиска количества элементов матрицы, больших заданного числа и расположенных выше главной диагонали } function CountAboveMainDiagonal(const x: matrix; n: integer; v: real): integer; var { Объявления локальных переменных } begin { Заглушка } result := (n * n - n) div 2; end; { Функция поиска количества элементов матрицы, больших заданного числа и расположенных выше побочной диагонали } function CountAboveSideDiagonal(const x: matrix; n: integer; v: real): integer; var { Объявления локальных переменных } begin { Заглушка } result := (n * n - n) div 2; end; begin if ParamCount < 2 then { Проверяем количество параметров } writeln('Недостаточно параметров!'); else begin if not FileExists(ParamStr(1)) then { Проверяем существование файла } writeln('Невозможно открыть файл ''', ParamStr(1), ''' для чтения'); else begin { Ввод исходных данных } AssignFile(f, ParamStr(1)); { Открываем файл } Reset(f); Get(a, na, na, f); Get(b, nb, nb, f); Get(c, nc, nc, f); readln(f, va, vb, vc); CloseFile(f); { Закрываем файл } { Поиск разностей между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали } kam := CountAboveMainDiagonal(a, na, va) - CountAboveSideDiagonal(a, na, va); kbm := CountAboveMainDiagonal(b, nb, vb) - CountAboveSideDiagonal(b, nb, vb); kcm := CountAboveMainDiagonal(c, nc, vc) - CountAboveSideDiagonal(c, nc, vc); { Вывод результатов } AssignFile(f, ParamStr(2)); Rewrite(f); Put(a, na, 'A', f); writeln(f, 'Заданное значение = ', va:8:2); writeln(f); Put(b, nb, 'B', f); writeln(f, 'Заданное значение = ', vb:8:2); writeln(f); Put(c, nc, 'C', f); writeln(f, 'Заданное значение = ', vc:8:2); writeln(f); if (da = db) and (db = dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, совпадает во всех трёх матрицах и равна ', da:2) else if (da = db) and (da < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах A и B и равна ', da:2) else if (da = dc) and (da < db) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах A и C и равна ', da:2) else if (db = dc) and (db < da) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрицах B и C и равна ', db:2) else if (da < db) and (da < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице A и равна ', da:2) else if (db < da) and (db < dc) then writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице B и равна ', db:2) else writeln(fout, 'Разность между количествами элементов, больших заданного числа и расположенных выше главной и побочной диагонали, минимальна в матрице C и равна ', dc:2); CloseFile(f); end; end; end.

Шаг 8. Разработка функций

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

{ Функция поиска количества элементов матрицы, больших заданного числа и расположенных выше главной диагонали } function CountAboveMainDiagonal(const x: matrix; n: integer; v: real): integer; var i, j: integer; begin result := 0; for i := 1 to n - 1 do for j := i + 1 to n do if x[i, j] > v then result := result + 1; end;

Функция поиска элементов матрицы, расположенных выше побочной диагонали, разрабатывается аналогично.