Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


ТЕМА: РЕАЛИЗАЦИЯ В ИНТЕГРИРОВАННОЙ СРЕДЕ ПРОГРАММИРОВАНИЯ TURBO PASCAL АЛГОРИТМОВ ЦИКЛИЧЕСКОЙ СТРУКТУРЫ.



ТЕМА: РЕАЛИЗАЦИЯ В ИНТЕГРИРОВАННОЙ СРЕДЕ ПРОГРАММИРОВАНИЯ TURBO PASCAL АЛГОРИТМОВ ЦИКЛИЧЕСКОЙ СТРУКТУРЫ.

ОДНОМЕРНЫЕ МАССИВЫ.

Цель работы: приобретение навыков работы в интегрированной среде программирования TURBO PASCAL; получить навыки программирования алгоритмов циклической структуры, работы с одномерными массивами и реализации их на ЭВМ.

Ч А С Т Ь 1.

Цикл – это фрагмент программы, повторяемый многократно. В паскале три оператора цикла – while, repeat и for. В принципе, без них можно обойтись, поскольку любой цикл можно реализовать с помощью условного оператора if и оператора перехода goto, но операторы цикла гораздо удобнее и нагляднее. У каждого из них есть предпочтительная область применения.

Все циклы имеют схожую структуру (рис.1.). Операторы, ради многократного выполнения которых организуется цикл, называют телом цикла. Остальные операторы служат для управления процессом повторения вычислений: это начальные установки, проверка условия продолжения цикла и модификация параметров параметра цикла. Один проход цикла называется итерацией.

 


На этапе начальных установок (до входа в цикл) задаются значения переменных, которые в нем используются. Эти значения могут задаваться явно или неявно.

Цикл завершается, если условие его продолжения не выполняется. Возможно принудительное завершение как текущей итерации (для этого применяется процедура continue), так и цикла в целом (процедура break и оператор goto). Передавать управление извне цикла не рекомендуется, потому что при этом не выполнятся начальные установки. Иными словами, выйти из цикла можно в любой момент, а войти – только в начало.

 

ИНДИВИДУАЛЬНЫЕ ЗАДАНИЯ

ЗАДАНИЕ № 1.

Составить алгоритм и написать программу, которая вычислит и выведет на экран в виде таблицы значения функции, заданной графически (см. задание № 1 практикума №5), на интервале от xнач до xкон с шагом dx. Интервал и шаг задать таким образом, чтобы проверить все ветви программы. Таблицу снабдить заголовком. ( Теоретический материал по данной теме изложен в лекциях № 6, 16 ).

ЗАДАНИЕ № 2.

Составить алгоритм и написать программу, которая вычисляет и выводит на экран в виде таблицы значения функции, заданной с помощью ряда Тейлора, на интервале от xнач до xкон с шагом dx с точностью . Таблицу снабдить заголовком и шапкой. Каждая строка таблицы должна содержать значение аргумента, значение функции и количество просуммированных членов ряда. ( Теоретический материал по данной теме изложен в лекциях № 6, 15 ).

 


Номер варианта З А Д А Н И Е
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.

 

ЗАДАНИЕ № 3.

Приложение № 1.

 

ПЕЧАТЬ ТАБЛИЦЫ ЗНАЧЕНИЙ ФУНКЦИИ

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

Исходными данными являются начальное значение аргумента xn, конечное значение аргумента xk и шаг изменения аргумента dx. Все величины – вещественные и могут принимать любые значения на числовой оси. Результатом работы программы должна быть таблица, состоящая из двух столбцов – значений аргумента и соответствующих им значений функции. Таблица должна выглядеть следующим образом:

X Y
-4.00 0.76
-3.00 -0.14
-2.00 -0.91
-1.00 -0.84
0.00 0.00
1.00 0.84
2.00 0.91
3.00 0.14
4.00 -0.76

Опишем алгоритм в словесной форме:

1. Ввести исходные данные: xn, xk, dx.

2. Вывести заголовок таблицы.

3. Принять xn в качестве первого значения аргумента.

4. Вычислить значение функции.

5. Вывести строку таблицы (текущее значение аргумента и соответствующее ему значение функции).

6. Перейти к следующему значению аргумента.

7. Если оно не превышает конечное значение, повторить шаги 4 – 6, иначе закончить.

Шаги 4 – 6 повторяются многократно, поэтому для их выполнения надо организовать цикл. На каждом проходе цикла требуется хранить одно значение аргумента и одно значение функции, поэтому для них достаточно завести по одной переменной вещественного типа (x и y). Переменная x будет содержать текущее значение аргумента, а y – соответствующее ему значение функции:

 

{***************************************************}

{Программа: TABL. }

{Цель: табулирование функции. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program TABL;

Var xn, xk, dx, x, y: real;

Begin

Writeln(‘Введите xn, xk, dx’);

Read(xn, xk, dx);

Wriyeln(‘---------------------‘);

Writeln(‘| x | y ‘);

Writeln( ‘--------------------‘);

x: =xn;

While x< =xk do

begin

y: =sin(x);

Writeln(‘|’, x: 9: 2, ‘ |’, y: 9: 2, ‘ |’);

x: =x+dx

end;

Writeln(‘----------------------‘)

End. {TABL}

 

Следует обратить внимание, что условие продолжения цикла записано в его заголовке и проверяется до входа в цикл. Таким образом, если задать конечное значение аргумента, меньшее начального, даже при отрицательном шаге цикл не будет выполнен ни разу. Параметром этого цикла, т.е. переменной, управляющей его выполнением, является x. Для правильной работы цикла необходимо присвоить параметру начальное значение до входа в цикл, поэтому блок начальных установок цикла присутствует в явном виде. В данном случае при отсутствии этого оператора переменной x будет присвоено значение 0, поскольку в Паскале глобальные переменные обнуляются автоматически. Для перехода к следующему значению аргумента текущее значение наращивается на величину шага и заносится в ту же переменную. Перед запуском программы для параметра цикла необходимо проверить:

ü присвоено ли ему начальное значение;

ü изменяется ли он на каждой итерации цикла;

ü верно ли записано условие продолжения цикла.

 

Приложение № 2.

ВЫЧИСЛЕНИЕ СУММЫ РЯДА

Написать программу вычисления значения функции sin с помощью степенного ряда с точностью по формуле

Этот ряд сходится на всей числовой оси. Для достижения заданной точности требуется суммировать члены ряда до тех пор, пока абсолютная величина очередного члена не станет меньше или равна . Запишем в общем виде формулу для вычисления n-го члена ряда:

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

Легко заметить, что (n+1)-й член ряда вычисляется после n-го, поэтому программа получится более простой и эффективной, если находить член ряда не с «нуля», а умножением предыдущего члена на некоторую величину. Найдем эту величину. Для этого запишем формулу для (n+1)-го члена ряда, подставив в предыдущее выражение (n+1) вместо n:

Теперь найдем выражение, на которое надо будет умножить Cn, чтобы получить Cn+1:

Запишем алгоритм вычисления суммы в словесной форме:

1. Ввести исходные данные (аргумент и точность).

2. Задать начальные значения номеру члена ряда, первому члену ряда и сумме ряда.

3. Организовать цикл:

1) вычислить очередной член ряда;

2) добавить его к сумме ряда;

3) перейти к следующему члену ряда;

4) проверить, достигнута ли точность вычислений.

4. Вывести значение функции.

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

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

 

{***************************************************}

{Программа: SINUS. }

{Цель: вычисление суммы ряда. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program SINUS;

Const MaxIter = 500;

Var x, eps, y, c: double;

n: integer;

done: boolean;

Begin

Writeln(‘Введите аргумент и точность: ’);

Readln(x, eps);

done: = true;

c: =x;

y: =c;

n: =1;

While abs( c ) > eps do

begin

c: =-c * sqr(x) / 2 / n / (2*n+1);

y: =y + c;

inc(n);

if n < = MaxIter then continue;

Writeln(‘|’Ряд расходится’);

Done: = false; break

end;

if done then Writeln(‘Аргумент: ‘, x: 10: 6,

‘Значение функции: ’, y: 10: 6,

‘Вычислено с точностью ‘, eps: 8: 6, ‘за’, n, ‘итераций’);

readln

End. {SINUS}

 

Первый член ряда равен x, поэтому, чтобы при первом проходе цикла значение второго члена вычислялось правильно, начальное значение n должно быть равно 1. Максимально допустимое количество итераций удобно задать с помощью именованной константы. Для аварийного выхода из цикла применяется процедура break, которая обеспечивает переход к первому после цикла оператору. Поскольку выход в случае как аварийного, так и нормального завершения цикла происходит в одну и ту же точку программы, вводится булева переменная done, которая предотвращает печать значений функции после выхода из цикла, когда точность вычислений не достигнута. Создание подобных переменных-«флагов», принимающих значение «истина» в случае успешного окончания вычислений и «ложь» в противном случае, является распространенным приемом программирования.

 

Приложение № 3.

КОЛИЧЕСТВО КВАДРАТОВ В ПРЯМОУГОЛЬНИКЕ

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

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

Текст программы:

 

{***************************************************}

{Программа: KVADRAT. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program KVADRAT;

Var a, b, k, n, buf: integer;

Begin

Writeln(‘Введите стороны прямоугольника’);

Read(a, b);

n: = 0;

Repeat

If a< b then begin

buf: = a; a: = b; b: = buf

end;

k: = a div b;

a: = a mod b;

Writeln(k, ‘ квадратов ‘, b, ‘ x ‘, b);

Inc(n, k)

Until a = 0;

Writeln(‘Всего квадратов: ‘, n);

Readln

End. {KVADRAT}

 

Приложение № 4.

 

ПИФАГОРОВЫ ЧИСЛА

Begin

For a: = 1 to n do

For b: = a to n do

Begin

cx: = sqr(a) + sqr(b);

c: = trunc(sqrt(cx));

if (sqr( c ) =cx) and (c < = n) then writeln(a: 3, b: 3, c: 3)

end

End. { PYTHAGOR }

 

Ч А С Т Ь 2.

В рассматриваемых программах были использованы простые переменные стандартных типов данных. В этом случае каждой области памяти для хранения одной величины соответствует свое имя. Если переменных много, программа, предназначенная для их обработки, получается длинной и однообразной. Поэтому в любом процедурном языке есть понятие массива – ограниченной совокупности однотипных величин. Элементы массива располагаются в памяти непрерывным блоком и имеют одно и то же имя. Различают элементы по порядковому номеру (индексу).

 

ИНДИВИДУАЛЬНЫЕ ЗАДАНИЯ

ЗАДАНИЕ № 4.

Составить алгоритм и написать программу, согласно своему варианту.

 

Номер варианта З А Д А Н И Е
1. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Сумму отрицательных элементов массива. 2. Произведение элементов массива, расположенных между максимальным и минимальным элементами. Упорядочить элементы массива по возрастанию.
2. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Сумму положительных элементов массива. 2. Произведение элементов массива, расположенных между максимальным по модулю и минимальным по модулю элементами. Упорядочить элементы массива по убыванию.
3. В одномерном массиве, состоящем из n целочисленных элементов, вычислить: 1. Произведение элементов массива с четными номерами. 2. Сумму элементов массива, расположенных между первым и последним нулевыми элементами. Преобразовать массив таким образом, чтобы сначала располагались все положительные элементы, а потом — все отрицательные (элементы, равные нулю, считать положительными).
4. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Сумму элементов массива с нечетными номерами. 2. Сумму элементов массива, расположенных между первым и последним отрицательными элементами. Сжать массив, удалив из него все элементы, модуль которых не превышает единицу. Освободившиеся в конце массива элементы заполнить нулями.
5. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Максимальный элемент массива. 2. Сумму элементов массива, расположенных до последнего положительного элемента. Сжать массив, удалив из него все элементы, модуль которых находится в интервале [а, b]. Освободившиеся в конце массива элементы заполнить нулями.
6. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Минимальный элемент массива. 2. Сумму элементов массива, расположенных между первым и последним положительными элементами. Преобразовать массив таким образом, чтобы сначала располагались все элементы, равные нулю, а потом — все остальные.
7. В одномерном массиве, состоящем из n целочисленных элементов, вычислить: 1. Номер максимального элемента массива. 2. Произведение элементов массива, расположенных между первым и вторым нулевыми элементами. Преобразовать массив таким образом, чтобы в первой его половине располагались элементы, стоявшие в нечетных позициях, а во второй половине — элементы, стоявшие в четных позициях.
8. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Номер минимального элемента массива. 2. Сумму элементов массива, расположенных между первым и вторым отрицательными элементами. Преобразовать массив таким образом, чтобы сначала располагались все элементы, модуль которых не превышает единицу, а потом — все остальные.
9. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Максимальный по модулю элемент массива. 2. Сумму элементов массива, расположенных между первым и вторым положительными элементами. Преобразовать массив таким образом, чтобы элементы, равные нулю, располагались после всех остальных.
10. В одномерном массиве, состоящем из n целочисленных элементов, вычислить: 1. Минимальный по модулю элемент массива. 2. Сумму модулей элементов массива, расположенных после первого элемента, равного нулю. Преобразовать массив таким образом, чтобы в первой его половине располагались элементы, стоявшие в четных позициях, а во второй половине — элементы, стоявшие в нечетных позициях.
11. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Номер минимального по модулю элемента массива. 2. Сумму модулей элементов массива, расположенных после первого отрицательного элемента. Сжать массив, удалив из него все элементы, величина которых находится в интервале [а, b]. Освободившиеся в конце массива элементы заполнить нулями.
12. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Номер максимального по модулю элемента массива. 2. Сумму элементов массива, расположенных после первого положительного элемента. Преобразовать массив таким образом, чтобы сначала располагались все элементы, целая часть которых лежит в интервале [а, b], а потом — все остальные.
13. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество элементов массива, лежащих в диапазоне от А до B. 2. Сумму элементов массива, расположенных после максимального элемента. Упорядочить элементы массива по убыванию модулей.
14. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество элементов массива, равных нулю. 2. Сумму элементов массива, расположенных после минимального элемента. Упорядочить элементы массива по возрастанию модулей.
15. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество элементов массива, больших С. 2. Произведение элементов массива, расположенных после максимального по модулю элемента. Преобразовать массив таким образом, чтобы сначала располагались все отрицательные элементы, а потом — все положительные (элементы, равные нулю, считать положительными).
16. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество отрицательных элементов массива. 2. Сумму модулей элементов массива, расположенных после минимального по модулю элемента. Заменить все отрицательные элементы массива их квадратами и упорядочить элементы массива по возрастанию.
17. В одномерном массиве, состоящем из п целочисленных элементов, вычислить: 1. Количество положительных элементов массива. 2. Сумму элементов массива, расположенных после последнего элемента, равного нулю. Преобразовать массив таким образом, чтобы сначала располагались все элементы, целая часть которых не превышает единицу, а потом — все остальные.
18. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество элементов массива, меньших С. 2. Сумму целых частей элементов массива, расположенных после последнего отрицательного элемента. Преобразовать массив таким образом, чтобы сначала располагались все элементы, отличающиеся от максимального не более чем на 20%, а потом — все остальные.
19. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Произведение отрицательных элементов массива. 2. Сумму положительных элементов массива, расположенных до максимального элемента. Изменить порядок следования элементов в массиве на обратный.
20. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Произведение положительных элементов массива. 2. Сумму элементов массива, расположенных до минимального элемента. Упорядочить по возрастанию отдельно элементы, стоящие на четных местах, и элементы, стоящие на нечетных местах.
21. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Сумму отрицательных элементов массива. 2. Произведение элементов массива, расположенных между максимальным и минимальным элементами. Упорядочить элементы массива по возрастанию.
22. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Максимальный элемент массива. 2. Сумму элементов массива, расположенных до последнего положительного элемента. Сжать массив, удалив из него все элементы, модуль которых находится в интервале [а, b]. Освободившиеся в конце массива элементы заполнить нулями.
23. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Номер минимального по модулю элемента массива. 2. Сумму модулей элементов массива, расположенных после первого отрицательного элемента. Сжать массив, удалив из него все элементы, величина которых находится в интервале [а, b]. Освободившиеся в конце массива элементы заполнить нулями.
24. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Количество элементов массива, больших С. 2. Произведение элементов массива, расположенных после максимального по модулю элемента. Преобразовать массив таким образом, чтобы сначала располагались все отрицательные элементы, а потом — все положительные (элементы, равные нулю, считать положительными).
25. В одномерном массиве, состоящем из n вещественных элементов, вычислить: 1. Произведение положительных элементов массива. 2. Сумму элементов массива, расположенных до минимального элемента. Упорядочить по возрастанию отдельно элементы, стоящие на четных местах, и элементы, стоящие на нечетных местах.

 

После выполнения данного практикума студент должен знать:

v Массив не является стандартным типом данных, он задается в разделе описания типов. Если тип массива используется только в одном месте программы, можно задать тип прямо при описании переменных.

v Размерность массива может быть только константой или константными выражениями. Рекомендуется задавать ее с помощью именованной константы.

v Тип элементов массива может быть любым, кроме файлового, тип индексов – интервальным, перечисляемым или byte.

v При описании массива можно задать начальные значения его элементов. При этом он описывается в разделе описания констант.

v С массивами в целом можно выполнять только одну операцию - присваивание. При этом массивы должны быть одного типа. Все остальные действия выполняются с отдельными элементами массива.

v Автоматический контроль выхода индекса за границы массива по умолчанию не выполняется. Можно включить его с помощью директивы {$R+}.

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

Приложение № 5.

 

КОЛИЧЕСТВО ЭЛЕМЕНТОВ МЕЖДУ МИНИМУМОМ И МАКСИМУМОМ

Begin

Writeln(‘Введите ‘, n, ‘ элементов массива’);

For i: =1 to n do

Begin

Writeln(‘a[‘, i: 2, ‘]=’);

Read(a[i])

End;

max: = a[1]; {принять за максимальный первый элемент массива}

For i: = 1 to n do {просмотреть массив, начиная с первого элемента}

if a[i]> max then max: = a[i];

writeln(‘Максимальный элемент: ’, max)

End. { MAX_ELEM }

 

Для решения поставленной задачи требуется знать не значение максимума, в его положение в массиве, т. е. индекс:

 

{***************************************************}

{Программа: INDEX_MAX_ELEM. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program INDEX _ MAX_ELEM;

Const n = 10;

Var a: array [1.. n] of integer; {массив}

i: integer; {номер текущего элемента}

imax: integer; {номер максимального элемента}

Begin

Writeln(‘Введите ‘, n, ‘ элементов массива’);

For i: =1 to n do

Begin

Writeln(‘a[‘, i: 2, ‘]=’);

Read(a[i])

End;

imax: = 1;

For i: = 1 to n do

if a[i]> a[imax] then imax: = i;

writeln(‘Номер максимального элемента: ’, imax);

writeln(‘Максимальный элемент: ’, a[imax])

End. { INDEX_MAX_ELEM }

 

В этой программе в переменной imax запоминается номер максимального из просмотренных элементов. По этому номеру осуществляется выборка элементов из массива.

Запишем уточненный алгоритм решения рассматриваемой задачи:

1. Определить, где в массиве расположены его максимальный и минимальный элементы:

· задать начальные значения индексов искомых максимального и минимального элементов (например, равные номеру его первого элемента, но можно использовать любые другие значения индекса, не выходящие за границу массива);

· просмотреть массив, поочередно сравнивая каждый его элемент с ранее найденными максимумом и минимумом. Если очередной элемент больше ранее найденного максимума, принять этот элемент за максимум (т.е. запомнить его индекс). Если очередной элемент меньше ранее найденного минимума, принять этот элемент за минимум.

2. Определить границы просмотра массива для поиска положительных элементов, находящихся между его максимальным и минимальным элементами:

· если максимум расположен в массиве раньше, чем минимум, принять левую границу просмотра равной индексу максимума, иначе – индексу минимума;

· если максимум расположен в массиве раньше, чем минимум, принять правую границу просмотра равной индексу минимума, иначе – индексу максимума.

3. Определить количество положительных элементов в найденном диапазоне:

· обнулить счетчик положительных элементов;

· просмотреть массив в указанном диапазоне. Если очередной элемент больше нуля, увеличить счетчик на единицу.

Для экономии времени значения элементов массива при отладке можно задать путем инициализации:

{***************************************************}

{Программа: NUM_POSITIV. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program NUM_POSITIV;

Const n = 10;

a: array [1.. n] of integer = (1, 3, -5, 1, -2, 1, -1, 3, 8, 4);

Var i: integer; {индекс текущего элемента}

imax: integer; {индекс максимального элемента}

imin: integer; {индекс минимального элемента}

ibeg: integer; {начало интервала}

iend: integer; {конец интервала}

count: integer; {количество положительных элементов}

Begin

For i: =1 to n do writeln(a[i]: 3);

Writeln;

imax: = 1;

imin: = 1;

For i: = 1 to n do

Begin

if a[i]> a[imax] then imax: = i;

if a[i]< a[imin] then imin: = i

end;

writeln(‘max= ’, a[imax]: 3, ‘min= ‘, a[imin]: 3);

if imax < imin then ibeg: = imax

else ibeg: = imin;

if imax < imin then iend: = imin

else iend: = imax;

count: = 0;

for i: = ibeg + 1 to iend – 1 do

if a[i] > 0 then inc(count);

writeln(‘Количество положительных: ’, count: 5)

End. { NUM_POSITIV }

 

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

§ элемент a[imin] расположен левее элемента a[imax];

§ элемент a[imin] расположен правее элемента a[imax];

§ элементы a[imin] и a[imax] совпадают.

Последняя ситуация имеет место, когда в массиве все элементы имеют одно и то же значение. Желательно также проверить, как работает программа, если элемент a[imin] и a[imax] расположены рядом, а также в начале и в конце массива (граничные случаи). В массиве должны присутствовать как положительные, так и отрицательные элементы.

 

Приложение № 6.

 

СУММА ЭЛЕМЕНТОВ ПРАВЕЕ ПОСЛЕДНЕГО ОТРИЦАТЕЛЬНОГО

Написать программу, которая для n вещественных элементов определяет сумму элементов, расположенных правее последнего отрицательного элемента.

В этой задаче количество элементов задано переменной величиной. Предполагается, что она будет известна на этапе выполнения программы до того, как будут вводиться сами элементы. Допустим также, что известно максимально возможное количество элементов. В этом случае память под массив можно выделить по «максимуму», а затем заполнить только часть этой памяти. Фактическое количество введенных элементов запоминается в переменной, которая затем участвует в организации циклов по массиву, задавая его верхнюю границу. Ниже приведена программа, иллюстрирующая этот подход. В ней выполняются только считывание элементов с клавиатуры и их вывод на экран:

{***************************************************}

{Программа: EXAMPLE. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program EXAMPLE;

Const n = 10000;

Var a: array [1.. n] of integer; {массив}

i: integer; {номер текущего элемента}

nf: integer; {фактическое количество элементов в массиве}

Begin

Writeln(‘Введите количество элементов массива’);

Readln(nf);

If nf > n then

Begin

Writeln(‘Превышение размеров массива’);

Exit

End;

Writeln(‘Ввести элементы массива’);

For i: =1 to nf do

Begin

Writeln(‘a[‘, i: 2, ‘]=’);

Read(a[i])

End;

For i: = 1 to n do writeln(‘a[’, i: 2, ‘]=’, a[i]: 4)

End. { EXAMPLE }

 

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

Если же стоит задача вводить заранее неизвестное количество чисел до тех пор, пока не будет введен какой-либо признак окончания ввода, то заранее выделить достаточное количество памяти не удастся и придется воспользоваться так называемыми динамическими структурами данных, например списком. Остановимся на первом предположении – что количество элементов массива вводится с клавиатуры до начала ввода самих элементов. Перейдем к созданию алгоритма решения задачи. По аналогии с предыдущей задачей, рассмотренной в приложении № 5, можно принять такое решение: просматривая массив с начала до конца, найти номер последнего отрицательного элемента, а затем организовать цикл суммирования всех элементов, расположенных правее него. Вот как выглядит построенная по этому алгоритму программа (следует отметить, что она далеко не так хороша, как может показаться с первого взгляда):

 

{***************************************************}

{Программа: SUM_ELEM_1. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program SUM_ELEM_1;

Const n = 10000;

Var a: array [1.. n] of real;

i: integer; {индекс текущего элемента}

ineg: integer; {номер последнего отрицательного элемента}

nf: integer; {фактическое количество элементов в массиве}

sum: real; {сумма элементов}

Begin

Writeln(‘Введите количество элементов массива’);

Readln(nf);

If nf > n then

Begin

Writeln(‘Превышение размеров массива’);

Exit

End;

Writeln(‘Ввести элементы массива’);

For i: =1 to nf do

Begin

Writeln(‘a[‘, i: 2, ‘]=’);

Read(a[i])

End;

Writeln(‘Исходный массив: ’);

For i: = 1 to nf do writeln(‘a[’, i: 2, ‘]=’, a[i]: 4);

Writeln;

For i: =1 to nf do

If a[i] < 0 then ineg: = i;

sum: = 0;

For i: = ineg + 1 to nf do sum: = sum +a[i];

writeln(‘Сумма: ’, sum: 7: 2)

End. { SUM_ELEM_1 }

 

Номер последнего отрицательного элемента массива формируется в переменной ineg. При просмотре массива в эту переменную последовательно записываются номера всех отрицательных элементов массива. Таким образом, после выхода из цикла в ней остается номер самого последнего элемента. Может возникнуть мысль с целью оптимизации программы объединить цикл нахождения номера последнего отрицательного элемента с циклами ввода и контрольного вывода элементов массива, но так делать не советую, потому что ввод данных, их вывод и анализ – разные по смыслу действия, и смешивание их в одном цикле не прибавит программе ясности. После отладки программы операторы вывода можно удалить или закомментировать.

Теперь перейдем к критическому анализу первой попытки решения задачи. Для массивов, содержащих отрицательные элементы, эта программа работает верно, но при их отсутствии выдает сумму всех элементов массива. Это связано с тем, что если в массиве нет ни одного отрицательного элемента, переменной ineg значение в цикле не присваивается. Оно остается равным значению, заданному по умолчанию. Следовательно, в программу необходимо внести проверку, есть ли в массиве хотя бы один отрицательный элемент. Для этого переменной ineg присваивается начальное значение, не входящее в множество допустимых индексов массива (например, -1). После цикла поиска номера отрицательного элемента выполняется проверка, сохранилось ли начальное значение ineg неизменным. Если да, то это означает, что условие a[i] < 0 в операторе не выполнилось ни разу и отрицательных элементов в массиве нет:

 

{***************************************************}

{Программа: SUM_ELEM_2. }

{Программист: Иванов И.И. }

{Дата выполнения: 10 апреля 2006 г. }

{***************************************************}

Program SUM_ELEM_2;

Const n = 10000;

Var a: array [1.. n] of real;

i: integer; {индекс текущего элемента}

ineg: integer; {номер последнего отрицательного элемента}

nf: integer; {фактическое количество элементов в массиве}

sum: real; {сумма элементов}

Begin

Writeln(‘Введите количество элементов массива’);

Readln(nf);

If nf > n then

Begin

Writeln(‘Превышение размеров массива’);

Exit

End;

Writeln(‘Ввести элементы массива’);

For i: =1 to nf do

Begin

Writeln(‘a[‘, i: 2, ‘]=’);

Read(a[i])

End;

Writeln(‘Исходный массив: ’);

For i: = 1 to nf do writeln(‘a[’, i: 2, ‘]=’, a[i]: 4);

Writeln;

Ineg: = -1;

For i: =1 to nf do

If a[i] < 0 then ineg: = i;

If ineg = -1 then writeln(‘Отрицательных лементов нет’)

else begin

sum: = 0;

For i: = ineg + 1 to nf do sum: = sum +a[i];

writeln(‘Сумма: ’, sum: 7: 2)

end

End. { SUM_ELEM_2 }

 


Поделиться:



Последнее изменение этой страницы: 2017-03-14; Просмотров: 820; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.264 с.)
Главная | Случайная страница | Обратная связь