Лабораторная работа № 3. Работа с последовательностями чисел
Работа с последовательностями чисел
Задачи лабораторной работы
Вопросы, изучаемые в работе
- Построение программы циклической структуры с использованием операторов арифметических и итеративных циклов, реализация последних с помощью условных переходов.
- Освоение типовых алгоритмов: вычисления суммы, произведения, поиск максимума, минимума во вводимой последовательности и их порядковых номеров.
- Использование операторов описания переменных для данных различных типов.
- Использование в программе контроля за входными данными и результатами расчета.
Задание (общее ко всем вариантам).
Составить программу обработки последовательно вводимых с клавиатуры чисел (пока не будет обработано заданное количество чисел, или не сработает условие окончания ввода). Полученный результат обработки вывести на экран.
Оформить отчет по работе аналогично оформлению отчета по работе № 2. Текст программы должен быть распечатан, результаты – переписаны от руки.
Требования к программе.
- Программа должна обрабатывать данные указанного типа в количестве до 100 чисел, если в программе не указано иное ограничение. Конкретное количество чисел вводить в программу с клавиатуры. Массивы не использовать.
- Все значения, на которые по смыслу накладываются ограничения, должны при вводе проверяться.
- Если в результате обработки данных результат не получен, при выводе программа должна сообщать об этом в понятной форме.
- При выводе на экран использовать длину выводимой строки не более 76 символов.
- Остальные требования – как и в предыдущих лабораторных работах.
Общие пояснения
1. Программы циклической структуры используются, когда необходимо несколько раз выполнить однотипные действия с различными данными. Если количество повторений тела цикла известно перед началом цикла, он называется арифметическим, если нет – итеративным. Для организации арифметического цикла в блок-схеме алгоритма используется блок "модификатор", а в программе – соответствующий ему оператор "for...".
Итеративный цикл строится с использованием блока "решение", в котором один из альтернативных путей представляет выход из тела цикла. В программе такой цикл может выполняться с помощью специальных операторов итеративных циклов или оператора условного перехода. В данной работе будет использоваться только "if..." оператор.
Рассмотрим сначала арифметический цикл. Оператор состоит из заголовка и тела цикла. Заголовок имеет вид:
for <имя параметра цикла> := <начальное значение> to <конечное значение> do
Далее идет тело цикла: простой или составной оператор (до символа ";"). Если оператор составной, он заключается в операторные скобки begin ... end;
В качестве параметра цикла можно использовать любую целочисленную переменную, в которой в это время не хранится нужное в дальнейшем значение. Эта переменная изменяется в цикле автоматически. Параметр цикла – это переменная, обычно играющая роль не только счетчика количества выполненных повторений цикла, но одновременно служащая порядковым номером обрабатываемого числа или элемента массива.
Начальное и конечное значения параметра цикла могут быть выражениями, но они вычисляются только один раз – при первом входе в цикл. В теле цикла они не должны меняться. При каждом возврате к заголовку в цикле, счетчик автоматически увеличивается на единицу.
Тело цикла выполняется, пока счетчик не станет больше конечного значения (если счетчик равен конечному значению – цикл выполняется). Если требуется организовать цикл, в котором параметр уменьшается на единицу с каждым возвратом, то используют ключевое слово "downto", вместо "to".
Примеры написания оператора:
for i:=1 to 25 do write('*'); {вывод строки из 25 *}
for k:=L+1 to N-1 do { значения L и N должны }
begin { быть определены до цикла }
. . .
end;
for i:=N downto 2 do S:=S+i; {Сумма целых чисел 2..N}
Если нужно менять счетчик с другим шагом (не один), используют второй счетчик, изменяющийся в теле цикла по рекуррентной формуле, например j:=j+3; или вычисляемый через первый счетчик, например: j:= 2+(i-1)*3;
Итеративные циклы для завершения требуют проверки такого условия, результат которого может измениться в процессе выполнения тела цикла. По выполнении этого условия осуществляется переход на оператор, следующий за телом цикла. Возврат на начало тела цикла в этом случае выполняется оператором безусловного перехода. В программе при такой организации цикла требуется иметь две метки:
Start:
. . .
if A=Priznak then goto Finish;
. . .
goto Start;
Finish: . . .
Часто проверяют условие продолжения цикла, и по его выполнению возвращаются на начало тела цикла, иначе цикл заканчивается. В этом случае достаточно обычно одной метки:
Start:
. . .
if A<>Priznak then goto Start;
. . .
Тело итеративного цикла при таких способах построения в скобки begin ... end заключать не обязательно.
2. Циклические процессы почти всегда требуют некоторых подготовительных действий, выполняемых до начала цикла. Это связано с использованием в теле цикла так называемых "рекуррентных соотношений", в которых некоторая переменная вычисляется с использованием своего старого значения, например:
N:=N-1; P:=-2*P/i; S:=S+A и т.д.
Все такие переменные перед циклом должны получить определенные значения, чтобы правильно вычисляться внутри цикла. Например, при вычислении суммы последовательно вводимых слагаемых, ячейка (переменная) для суммы должна обнуляться; переменная для накопления произведения делается равной единице (или первому сомножителю).
Поиск максимумов (минимумов) или их порядковых номеров в рядах значений также выполняется по рекуррентным зависимостям (если новая величина больше максимума, сделаем максимум равным...) – сперва используется старое значение максимума, чтобы создать новое значение.
При поисках максимума можно использовать два варианта начального задания: или в качестве максимума берется первое рассматриваемое значение (и цикл начинает выполняться начиная со второго числа), или в качестве начального задается фиктивное значение – гарантированно меньшее, чем любое число сравниваемого ряда (т.е. теоретически минимальное возможное число). При этом циклическая обработка одинаково выполняется для всех чисел, начиная с первого.
3. Если в программе требуется обрабатывать нечисловые данные, для них можно заводить переменные нечисловых типов, которые также необходимо включить в блок описаний. Для символьных переменных используется описатель char, а для логических – описатель boolean. Например:
VAR
i,j :integer;
A,S :real;
C,Sim :char;
Q,Priz:boolean;
. . .
Символьные переменные можно сравнивать с символьными константами и между собой с помощью всех операций отношений (=,<,>, и т.д.), например:
if Sim > 'A' then ... или
if C = Sim then ...
Логические переменные можно использовать в условных операторах, причем не нужно записывать if Q=TRUE then..., а просто if Q then... , так как само значение Qможет быть TRUE или FALSE.
Наконец несколько замечаний по контролю за вводимыми величинами. Поскольку в программе предполагается ввод исходных данных пользователем программы путем набора значений на клавиатуре, в программе должны быть предусмотрены выводы на экран запросов на ввод того или иного параметра, нужного программе. Эти запросы представляют собой операторы вывода некоторого текста, например:
Writeln(' Сколько чисел будет обрабатываться?'); или
Writeln(' Вводи очередной сомножитель');
Такие запросы должны быть перед каждым оператором ввода данных с клавиатуры. Другой момент, который следует отметить, это необходимость контроля за вводимыми величинами. Недопустимое значение может не только привести к неправильному ответу, но и просто "подвесить" программу или привести к ее аварийному снятию операционной системой. Поэтому все данные, на которые по их смыслу (или по возможностям реализованного метода решения) накладываются ограничения, должны проверяться после их ввода на попадание в допустимый диапазон.
Обычно считается, что можно найти сумму нуля и большего количества слагаемых, произведение одного или более сомножителей, выбрать наибольшее или найти среднее значение из одного или нескольких чисел, вычислить факториал нуля или большего целого числа и т.д. Иногда ограничения накладываются не только снизу, но и сверху.
Если, например, допустимый диапазон для значений переменной A ограничен числами –0.5 и 11.0, то проверку на ошибочное значение можно осуществить оператором:
if (A > 11.0) or (A < -0.5) then ...
Если такая проверка даст значение TRUE (т.е. A имеет недопустимое значение), тогда нужно выдать сообщение об этом и либо закончить выполнение программы, либо (что более разумно) вернуться к оператору запроса ввода этой величины еще раз. Так как оба эти действия следует выполнять по срабатыванию одного и того же условия, операторы, задающие эти действия следует поместить в скобки begin ... end, например:
if (A > 11.0) or (A < -0.5) then
begin
Writeln(' Вы задали недопустимое значение');
goto Vvod_A;
end; { здесь Vvod_A – метка перед оператором запроса на ввод параметра, соответствующего переменной A }
Наконец, следует помнить, что не при всяких наборах исходных данных задача может иметь решение. Если по каким-либо причинам ответ выдать невозможно, следует об этом сообщить в понятной форме, а не выводить неправильное или невозможное для ответа значение. Например, если в задаче требуется делить что-то на сумму нескольких чисел с разными знаками, то сумма может случайно оказаться равной нулю, после чего деление невозможно и решения у задачи не окажется.
Тогда выдача результата может выглядеть так:
. . .
if Sum = 0 then
Writeln(' Нет решения, так как сумма равна 0')
else
begin
R:=.../Sum;
Writeln(' Отношение =', R:...);
end;
Разбор контрольного варианта
Задание
Таблица 12. Данные к заданию 31 варианта
№ вар. | Задание | Остановить обработку при… | Тип обрабат. данных |
Нахождение номера последнего числа, превышающего значение 10.5 в последовательности вводимых произвольных чисел. | …вводе заказанного количества чисел | Вещественые |
Решение задачи следует начинать с разбора задания и выделения объектов, упоминающихся или подразумевающихся в задании. Для каждого найденного объекта определяется его тип и придумывается имя (идентификатор) для последующего программирования. Имена, типы и назначения сводятся в таблицу идентификаторов.
Для данной задачи можно выделить: номер последнего числа, превышающего значение 10.5; количество чисел (N); вводимое число. Для запоминания искомого номера нужно знать порядковый номер вводимого числа. В задании оговорено, что вводимые числа – произвольные, т.е. могут быть как целыми, так и дробными, для их хранения в ЭВМ нужно иметь переменную (ячейку) вещественного типа. Текущий номер и искомый номер – величины целые и, вообще говоря, положительные. Для них можно завести или целые или беззнаковые переменные. Общее количество чисел также должно быть целым и больше нуля, иначе задача не имеет смысла. Таким образом, имеем таблицу:
Таблица 13. Идентификаторы программы 31-го варианта
Имя | Тип | Размер, байт | Назначение | |||
N | Целый | Количество чисел | ||||
I | Целый | Текущий номер | ||||
Num | Целый | Номер последнего числа, которое > 10.5 | ||||
A | Вещественый | Текущее число | ||||
Исходными данными в задаче являются, во-первых, количество чисел, а во-вторых, сами числа, последовательно вводимые в переменную A. Результатом будет порядковый номер последнего из чисел, которое превышает 10.5. Возможно, что среди вводимых чисел не найдется ни одного такого числа. В этом случае в конце необходимо выдать об этом сообщение, а не номер числа.
Контроль допустимости вводимых данных необходим только для количества чисел: оно должно быть не меньше единицы.
Алгоритм задачи состоит из трех последовательных обобщенных шагов: ввода данных, определения искомого номера и вывода результата.
В части ввода данных программа должна получить от пользователя значение количества чисел (N). Так как ввод данных выполняет человек с помощью клавиатуры, программа должна сообщить, что от него требуется.
Всякому вводимому с клавиатуры числу должен предшествовать запрос на дисплее: что вводить и в какой форме. Как и любое значение, вводимое пользователем с клавиатуры, количество чисел (N) должно контролироваться на допустимость введенной величины.
Если введено недопустимое значение, требуется выполнить два действия: сообщить об этом и вернуться на запрос нового значения N. Возврат назад возможен двумя способами: командой перехода на метку, поставленную перед оператором запроса или оператором итеративного цикла, причем цикла с "постусловием", так как один раз цикл должен выполниться обязательно.
В данном случае используем первый способ, и потому в программе появляется еще один объект – метка. Дадим ей имя vvod.
Кроме того, дадим имя нашей программе, например laborator_N_3. В результате в таблице имен добавится две строки:
Таблица 14. Окончание таблицы идентификаторов
Имя | Тип | Р-р, байт | Назначение |
laborator_N_3 | Имя программы | - | Поиск номера определенного числа |
vvod | Метка | - | Возврат по ошибке ввода |
Алгоритм
Раздел поиска номера обычно включает подготовку и цикл поиска. Так как количество чисел известно, используется арифметический цикл. В тело цикла входит получение очередного числа и, если нужно, запоминание его номера. Если встретится хотя бы одно число, удовлетворяющее условию превышения значения 10.5, номер будет найден, иначе нужно иметь признак, что такого числа не встретилось. В качестве такого признака можно использовать переменную Num, в которую перед циклом поиска заносится значение, невозможное для номера числа: например, –1. Если после цикла Num останется равным –1, следовательно, искомых чисел не встретилось.
Таким образом, раздел поиска включает присваивание начального значения переменной Num и цикл, тело которого содержит запрос ввода очередного числа, прием и занесение его в переменную для текущего числа A; проверку, что A>10.5, и если так, запоминание текущего номера в переменной Num. Цикл поиска нужно вести до конца, так как нас интересует последнее число, удовлетворяющее условию выбора.
По окончании раздела поиска, в разделе вывода результатов, печатается найденный номер Num, если он не равен –1, иначе выдается сообщение об отсутствии чисел, удовлетворяющих условию задачи. Построение алгоритма здесь приведено очень подробно, чтобы пояснить весь ход рассуждений. В последующих работах примеры построения алгоритмов будут даваться в укрупненном виде – т.е. только основные идеи. Для разработки алгоритма стоит обратиться к материалам лекции по структурному программированию.
Рисунок 6. Алгоритм 31-го варианта
На основании построенного алгоритма можно написать текст программы, причем таблица идентификаторов используется для создания раздела описаний, а алгоритм – для выполняемого блока. При написании учтем требования к оформлению текста программы.
Получим следующую программу на Паскале.
Текст программы
PROGRAM laborator_N_3;
{ Программа Лабораторной работы N 3
Вариант N 31.
гр. Я-007, ст. Умненькая И.Я. }
VAR N,Num,i :integer;
A :real;
LABEL vvod;
BEGIN { Выполняемый блок.
Первый раздел - ввод данных }
vvod: writeln('Сколько будет чисел?');
readln(N);
if N < 1 then
begin
writeln('Нельзя рассматривать меньше 1 числа');
goto vvod;
end;
{ Основной раздел - поиск номера }
Num:= -1; {задание признака отсутствия подходящих чисел}
for i:=1 to N do
begin
writeln('Введите очередное число');
readln(A);
if A > 10.5 then { если число удовлетворяет
условию задачи }
Num:=i; { запоминаем его номер }
end;
{ Раздел вывода результатов поиска }
if Num=-1 then writeln('Подходящих чисел не было')
else
writeln('Номер последнего числа,>10.5 равен ',
Num);
END.
Варианты заданий
Таблица 15. Варианты заданий лабораторной работы № 3
№ вар. | Задание | Остановить обработку при… | Тип обраб. данных |
Вычисление произведения последовательно вводимых чисел | …превышении абсолютной величины произведения 1000.0, или при вводе числа 0 | Веществ. | |
Вычисление суммы только четных чисел из последовательно вводимых чисел | …вводе заказанного количества чисел | Целые | |
Нахождение номера минимального значения в последовательности вводимых чисел | …вводе признака конца – предварительно введенного пользователем числа | Целые | |
Вычисление суммы только положительных чисел изпоследовательно вводимых чисел | …превышениисуммы 100.0 | Веществ. | |
Нахождение максимального значения в последовательности вводимых чисел. При поиске пропускать числа из диапазона от 10.1 до 50.1. | …вводе заказанного количества чисел | Веществ. | |
Вычисление суммы последовательно вводимых чисел | …вводе признака конца – значения из заранее выбранного пользователем диапазона | Веществ. | |
Нахождение минимального значения среди последовательности вводимых чисел. Сам признак конца при определении минимума не учитывать. | …вводе признака конца – предварительно введенного пользователем числа из диапазона -10..5 | Целые | |
Вычисление произведения последовательно вводимых чисел заданного количества | …вводе заказанного количества чисел – не меньше 5 но и не более 10 | Веществ. | |
Нахождение минимального значения из чисел, кратных трем, среди последовательности вводимых чисел. | …вводе заказанного количества чисел | Целые | |
Вычисление суммы последовательно вводимых чисел | …превышении абсолютной величины суммы 100.1 | Веществ. | |
Нахождение максимального из последовательно вводимых чисел | …вводе признака конца – предварительно выбранного пользователем числа | Целые беззнаковые | |
Вычисление произведения последовательно вводимых чисел | …вводе признака конца – числа из диапазона от -5 до 5 (включительно) | Целые | |
Нахождение номера максимального значения, кратного пяти, в последовательности вводимых чисел | …вводе признака конца – предварительно выбранного пользователем числа | Целые | |
Вычисление факториала вводимого числа. Если результат не помещается в 4 байта, программа должна сообщать об этом | Факториалом целого числа N (обозначается N!) называется произведение всех целых чисел от 1 до N. По определению, 0!=1 | Длинные целые (4 байта) | |
Вычисление среднеарифметического тех из последовательно вводимых чисел, которые попадают в диапазон от 2.0 до 5.0 включительно. | …вводе заказанного количества чисел | Веществ. | |
Нахождение номера максимального отрицательного значения в последовательности произвольных вводимых чисел | …вводе признака конца – предварительно выбранного пользователем числа | Веществ. | |
Вычисление произведения только отрицательных из последовательно вводимых произвольных чисел | …вводе заказанного количества чисел | Веществ. | |
Нахождение номера наименьшего положительного числа в последовательности произвольных чисел, вводимых с клавиатуры | …вводе заказанного количества чисел | Веществ. | |
Вычисление среднеарифметического последовательно вводимых чисел | …вводе третьего отрицательного значения, которое рассматривать как признака конца, а не число. | Веществ. | |
Нахождение максимального отрицательного значения в последовательности вводимых произвольных (как положительных, так и отрицательных) чисел | …вводе заказанного количества чисел | Целые | |
Вычисление среднего значения только положительных элементов среди вводимых произвольных чисел | …вводе заказанного количества чисел | Веществ. | |
Нахождение разности номеров первого и последнего отрицательных чисел в последовательности водимых чисел | …вводе заказанного количества чисел | Целые | |
Вычисление среднеарифметического только отрицательных чисел среди произвольных вводимых чисел | …вводе признака конца (выбранного пользователем произвольного числа). | Веществ. | |
Нахождение разности максимального и минимального значений в последовательности вводимых чисел | …вводе заказанного количества чисел | Целые | |
Вычисление суммы только отрицательных чисел, абсолютная величина которых превышает 8.5, из последовательно вводимых произвольных чисел | …вводе заказанного количества чисел | Веществ. | |
Нахождение минимального значения среди последовательности вводимых чисел, из которых рассматриваются только четные | …вводе заказанного количества чисел | Целые | |
Вычисление отношения суммы всех положительных чисел к сумме всех отрицательных в последовательности вводимых чисел | …вводе заказанного количества чисел | Веществ. | |
Нахождение разности номеров максимального и минимального значений в последовательности вводимых чисел | …вводе заказанного количества чисел | Веществ. | |
Вычисление среднеарифметического значения только отрицательных элементов после первого 0 среди вводимых произвольных вещественных чисел | …вводе заказанного количества чисел | Веществ | |
Вычисление отношения суммы всех положительных чисел к сумме всех чисел в последовательности вводимых чисел | …вводе признака конца – числа 0 | Веществ. | |
Нахождение номера последнего числа, превышающего значение 10.5 в последовательности вводимых произвольных чисел | …вводе заказанного количества чисел | Веществ. |