Задача «Обработка одномерного массива»

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

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

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

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

Из постановки задачи следует, что на вход программы подаются два одномерных массива – A и C. Тип элементов массивов не указан, поэтому возьмём вещественный тип, как более общий случай. Кроме того, чтобы можно было вводить и обрабатывать массивы разной длины, необходима переменная, хранящая количество элементов массивов, – n. Она будет иметь целый тип, т.к. количество не может быть дробным. Также из постановки задачи следует, что необходимо задать границы числового отрезка b и d. Эти переменные будут вещественными, также как и элементы массивов.

Опять-таки из постановки задачи следует, что прежде всего надо проверить наличие в массиве A положительного элемента. Результатом работы этой части программы будут переменные exists и np – признак наличия положительного элемента и его номер. Первая переменная будут логической, вторая – целой. Затем надо найти сумму s и количество k элементов массива A, которые попадают на отрезок от b до d. Сумма вещественных элементов массива будет вещественной, а количество – целым. Также надо найти imin – номер наименьшего по абсолютной величине элемента массива C. Эта переменая будет целой.

По определению отрезок включает свои конечные точки, поэтому будем использовать нестрогие неравенства.

Для задания массива введём константу, ограничивающую максимально возможное количество элементов массива, и тип для массива. program Arrays; const nmax = 10; type mas = array [1..nmax] of real; var { Входные данные } a: mas; { вещ a[1..n] – исходный массив } c: mas; { вещ c[1..n] – исходный массив } n: integer; { цел n – количество элементов массивов } b, d: real; { вещ b, d – границы отрезка } { Выходные данные } exists: boolean; { лог exists – признак наличия положительного элемента } np: integer; { цел np – номер положительного элемента } s: real; { вещ s – сумма элементов массива, попадающих на заданный отрезок } k: integer; { цел k – количество элементов массива, попадающих на заданный отрезок } imin: integer; { цел imin – номер наименьшего по абсолютной величине элемента массива } begin { Обработка данных } end.

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

Из постановки задачи следует, что все входные данные можно разделить на две группы – для случаев, когда в массиве A есть положительные элементы и когда их нет. Также надо рассмотреть случаи, когда в массиве A есть элементы, попадающие на заданный отрезок, и когда таких элементов нет. В случае поиска номера номера наименьшего по абсолютной величине элемента массива C, необходимо рассмотреть случаи, когда искомый элемент является первым, последним или находится в середине массива.

№ теста Входные данные Ожидаемые результаты Смысл теста
1 n = 5
a = {-2, 3, 0, 5, 8}
c = { 1, 2, 3, 4, 5}
b = 0, d = 6
s = 8
k = 3
В массиве A есть положительный элемент. В массиве A есть как элементы, удовлетворяющие условию, так и элементы, не удовлетворяющие условию.
2 n = 5
a = {-2, 3, 0, 5, 8}
c = { 1, 2, 3, 4, 5}
b = -10, d = 10
s = 14
k = 5
В массиве A есть положительный элемент. Все элементы массива A удовлетворяют условию.
3 n = 3
a = {-2, 15, -7}
c = { 1,  2,  3}
b = 2, d = 10
В массиве нет элементов, попадающих на отрезок [2; 10] В массиве A есть положительный элемент. Нет элементов массива A, удовлетворяющих условию.
4 n = 5
a = {-1, -2, -3, -4, -5}
c = {12,  3, -2,  5,  8}
b = 0, d = 5
imin = 3 В массиве A нет положительных элементов. Минимальный по модулю элемент массива C находится в середине массива. Минимальный по модулю элемент совпадает с минимальным элементом.
5 n = 5
a = {-1, -2, -3, -4, -5}
c = {12,  3,  6, -5,  8}
b = 0, d = 5
imin = 2 В массиве A нет положительных элементов. Минимальный по модулю элемент массива C находится в середине массива. Минимальный по модулю элемент не совпадает с минимальным элементом.
6 n = 4
a = {-1, -2, -3, -4}
c = { 1, -5,  7, 13}
b = 0, d = 5
imin = 1 В массиве A нет положительных элементов. Минимальный по модулю элемент массива C – первый в массиве. Минимальный по модулю элемент не совпадает с минимальным элементом.
7 n = 4
a = { -1,  -2,  -3, -4}
c = {-25, -15, -10, -5}
b = 0, d = 5
imin = 4 В массиве A нет положительных элементов. Минимальный по модулю элемент массива C – последний в массиве. Минимальный по модулю элемент не совпадает с минимальным элементом.

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

Программа должна состять из трёх основных частей – ввод исходных данных, получение результатов, вывод полученных результатов. program Arrays; const nmax = 10; type mas = array [1..nmax] of real; var { Входные данные } a: mas; { вещ a[1..n] – исходный массив } c: mas; { вещ c[1..n] – исходный массив } n: integer; { цел n – количество элементов массивов } b, d: real; { вещ b, d – границы отрезка } { Выходные данные } exists: boolean; { лог exists – признак наличия положительного элемента } np: integer; { цел np – номер положительного элемента } s: real; { вещ s – сумма элементов массива, попадающих на заданный отрезок } k: integer; { цел k – количество элементов массива, попадающих на заданный отрезок } imin: integer; { цел imin – номер наименьшего по абсолютной величине элемента массива } begin { Ввод исходных данных } { Решение задачи } { Вывод результатов } end.

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

Запрограммируем ввод и вывод согласно входной и выходной форме. Поскольку требуется организовать ввод из файла, входная форма будет достаточно простой, т.к. при вводе из файла не требуется писать приглашения «введите ...».

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

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

Массив – это переменная структурированного типа, поэтому его нельзя ввести одной операцией ввода (и нельзя вывести одной операцией вывода). Поскольку массив состоит из однотипных элементов, он реализует повтор, и для обработки (для любой обработки, в том числе для ввода и вывода) нужна управляющая структура, которая также реализует повтор, т.е. цикл. Удобнее всего использовать параметрический цикл. Для этого нам понадобится промежуточная переменная i – параметр цикла, которую можно объявлять непосредственно в цикле for. Также нам потребуется файловая переменная для работы с файлами. Достаточно одной переменной, т.к. после чтения данных файл будет закрываться, и ту же самую файловую переменную можно использовать для работы с выходным файлом.

В качестве заглушки для обработки данных напишем пока присваивание значения ложь переменной exists и значения 0 переменным np, s, k и imin. Пока будем выводить все выходные данные.

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

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

program Arrays; const nmax = 10; type mas = array [1..nmax] of real; var { Входные данные } a: mas; { вещ a[1..n] – исходный массив } c: mas; { вещ c[1..n] – исходный массив } n: integer; { цел n – количество элементов массивов } b, d: real; { вещ b, d – границы отрезка } { Выходные данные } exists: boolean; { лог exists – признак наличия положительного элемента } np: integer; { цел np – номер положительного элемента } s: real; { вещ s – сумма элементов массива, попадающих на заданный отрезок } k: integer; { цел k – количество элементов массива, попадающих на заданный отрезок } imin: integer; { цел imin – номер наименьшего по абсолютной величине элемента массива } { Промежуточные данные } 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); readln(f, n); for i: integer := 1 to n do read(f, a[i]); for i: integer := 1 to n do read(f, c[i]); readln(f, b, d); CloseFile(f); { Закрываем файл } { Решение задачи – заглушка } exists := false; np := 0; s := 0; k := 0; imin := 0; { Вывод результатов } AssignFile(f, ParamStr(2)); Rewrite(f); writeln(f, 'Массив A из ', n:2, ' элементов'); for i: integer := 1 to n do write(f, a[i]:8:2, ' '); writeln(f, 'Массив C из ', n:2, ' элементов'); for i: integer := 1 to n do write(f, c[i]:8:2, ' '); writeln(f); writeln(f); if exists then writeln(f, 'В массиве A есть положительный элемент, его номер = ', np:2) else writeln(f, 'В массиве A нет положительных элементов'); if k = 0 then writeln('В массиве A нет элементов, попадающих на отрезок [', b:4:2, '; ', d:4:2, ']') else begin writeln('Сумма элементов массива A, попадающих на отрезок [', b:4:2, '; ', d:4:2, '] = ', s:8:2); writeln('Количество элементов массива A, попадающих на отрезок [', b:4:2, '; ', d:4:2, '] = ', k:2); end; writeln(f, 'Номер наименьшего по абсолютной величине элемента массива C = ', imin:2); CloseFile(f); end; end; end.

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

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

Для решения данной задачи сначала надо проверить наличие положительных элементов в массиве A. Если такой элемент есть, то будем искать сумму и число тех элементов массива A, которые попадают на заданный отрезок. Иначе будем определять номер наименьшего по абсолютной величине элемента массива C.

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

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

Информацию о методах поиска элементов, удовлетворяющих условию, методах подсчёта количества и накопления сумм/произведений и методах поиска экстремума см. в соответствующих разделах практических занятий.

Структура той части программы, которая реализует вывод результатов, повторяет структуру вычислительной части программы.

program Arrays; const nmax = 10; type mas = array [1..nmax] of real; var { Входные данные } a: mas; { вещ a[1..n] – исходный массив } c: mas; { вещ c[1..n] – исходный массив } n: integer; { цел n – количество элементов массивов } b, d: real; { вещ b, d – границы отрезка } { Выходные данные } exists: boolean; { лог exists – признак наличия положительного элемента } np: integer; { цел np – номер положительного элемента } s: real; { вещ s – сумма элементов массива, попадающих на заданный отрезок } k: integer; { цел k – количество элементов массива, попадающих на заданный отрезок } imin: integer; { цел imin – номер наименьшего по абсолютной величине элемента массива } { Промежуточные данные } i: integer; { цел i – параметр цикла while } 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); readln(f, n); for i: integer := 1 to n do read(f, a[i]); for i: integer := 1 to n do read(f, c[i]); readln(f, b, d); CloseFile(f); { Закрываем файл } { Решение задачи } exists := false; np := 0; { Проверка наличия положительных элементов в массиве A } if exists then { Поиск суммы и количества элементов массива A, которые попадают на заданный отрезок } else { Поиск номера наименьшего по абсолютной величине элемента массива C} { Вывод результатов } AssignFile(f, ParamStr(2)); Rewrite(f); writeln(f, 'Массив A из ', n:2, ' элементов'); for i: integer := 1 to n do write(f, a[i]:8:2, ' '); writeln(f, 'Массив C из ', n:2, ' элементов'); for i: integer := 1 to n do write(f, c[i]:8:2, ' '); writeln(f); writeln(f); if exists then begin writeln(f, 'В массиве A есть положительный элемент, его номер = ', np:2) if k = 0 then writeln('В массиве A нет элементов, попадающих на отрезок [', b:4:2, '; ', d:4:2, ']') else begin writeln('Сумма элементов массива A, попадающих на отрезок [', b:4:2, '; ', d:4:2, '] = ', s:8:2); writeln('Количество элементов массива A, попадающих на отрезок [', b:4:2, '; ', d:4:2, '] = ', k:2); end; end else begin writeln(f, 'В массиве A нет положительных элементов'); writeln(f, 'Номер наименьшего по абсолютной величине элемента массива C = ', imin:2); end; CloseFile(f); end; end; end.