Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
83
Добавлен:
10.02.2016
Размер:
930.82 Кб
Скачать

1.2.2. Общие вопросы организации циклов

Выше были рассмотрены примеры циклических алгоритмов, которые часто встречаются в практике. Прежде чем перейти к особенностям орга-низации циклических процессов, рассмотрим ещё один типичный пример.

Пример 1.9. Пусть СП вычисления EXP в нашем распоряжении нет, и нам самим требуется составить соответствующий алгоритм. Запишем разложение exp(-x) в ряд Тейлора, ограничившись n-м членом:

(1.15)

Обозначим hi общий член ряда:

(1.16)

Тогда ряд (1.15) может быть представлен выражением

(1.17)

Вычисления hi можно проводить двояко:

 непосредственно по (1.16);

 используя рекуррентную связь между значениями h, индексы которых отличаются на единицу.

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

. (1.18)

Ясно, что второй способ более рациональный.

При вычислении суммы ряда (1.17) также более рационально использовать предыдущие результаты:

, (1.19)

где Si - значение частичной суммы членов ряда с 1-го по i-й включительно.

Нетрудно видеть, что при определении значения y=exp(-x) для конкретного значения x=x0 достаточно организовать один цикл, в котором объединить вычисления значений hi и Si.

В общем случае представления функции рядом она может быть записана как

yn = , (1.20)

где qi - коэффициенты разложения функции в ряд.

При вычислении значений рядов возможны два варианта организации вычислительного процесса (точнее, определения момента его окончания):

  • n задано или известно в результате анализа погрешности ряда (константа n – исходное данное). Чаще всего это бывает, если опреде-ляется значение функции для одного конкретного значения x=x0 или небольшого числа мало отличающихся (в том смысле, что для них n не изменяется) значений x. Тогда организуются циклические вычисления, которые заканчиваются при достижении параметром i цикла значения n;

  • n заранее неизвестно, однако задана допустимая погрешность , и циклический процесс заканчивается по условию выполнения неравенства

yn+1-yn  , (1.21)

или

Rn(x)  , (1.22)

где Rn(x) - остаточный член ряда (константа Rn вычисляется заранее).

В примере 1.9 ряд является знакопеременным, поэтому [4] погрешность ряда не превышает значения первого отброшенного его члена, равного

Rn(x) (1.23)

Вычислительный процесс организуется по-разному в случае вычис-ления у=f(x) для конкретного значения x=x0 и для некоторого множества значений xi (например, необходимо построить график у=f(x), ахв). В пер-вом случае вычисление выполняется однократно и потому нет необходи-мости в дополнительной организации вычислительного процесса; во втором случае необходимо организовать циклический перебор всех значений xi, используя номера i-x точек на оси ОХ при неравномерном разбиении отрезка [a, b] либо приращение по х,

(1.24)

при равномерном разбиении на к интервалов (к - известно), и тогда

xi = a + i*x. (1.25)

Отметим, что полином Qn(x) может быть записан аналогично (1.20). Однако ряд и полином существенно отличаются: ряд имеет общий член, так как коэффициенты ряда вычисляются по определённому закону, а у полинома коэффициенты могут быть произвольными, поэтому у него может отсутствовать общий член. Вопрос определения n для полинома должен решаться отдельно в каждом конкретном случае.

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

Стандартные способы построения циклов в программировании – использование конструкций for, while <условие> do <оператор>, repeat <оператор> until <условие> (рис. 1.15).

Оператор for имеет внутренний счётчик в обоих вариантах реали-зации (Iнач, Iкон - целые константы):

for I:= Iнач to Iкон do <оператор> - счёт в прямом направлении;

for I:= Iкон downto Iнач do <оператор> - счёт в обратном направлении.

Здесь изменение параметра цикла происходит на 1 по умолчанию; в некоторых языках программирования используется явное указание на шаг (step) приращения I.

Применять оператор for целесообразно при известном числе повторений в цикле.

На рис. 1.15,а и б приведены фрагменты СА для оператора for; здесь S1, S2 - тело цикла.

Запишем фрагмент программы примера 1.6 (строки 3-9) с использо-ванием оператора for (здесь invel(lel, rel) - процедура инверсии элементов):

с:=А[1];

for i:=1 to n-1 do

begin

lel:=c; rel:=A[i+1];

if lel<rel then invel(lel,rel);

c:=rel

end;

minel:=c;

Этот же фрагмент можно упростить, исключив процедуру invelи соответственно переменныеlel и rel (на каждом шаге запоминается мини-мальное значениеспары элементов):

c:=A[1];

for i:=2 to n do

begin

if ca[i] then c:=a[i]; (*текущий минимальный элемент*)

end;

minel:=c;

Реализация операторов while...do и repeat...until в виде СА приведена на рис. 1.15,в и г. Смысл этих операторов заключается в следующем: для первого - пока выполняется условие W, делать S1, S2,..., а для второго - повторять S1, S2,..., пока не выполнится условие U. Раз-личие этих условных операторов заключается в том, что при организации одного и того же вычислительного процесса (S1; S2;..., Sn) условия W и U должны быть противоположны, U=; кроме того, во втором случае после-

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

Эти операторы можно использовать и при известном числе повторе-ний; при этом в теле цикла должен быть предусмотрен счётчик, а усло-вием выхода из цикла будет его конечное значение.

Операторы while...do и repeat...until так же, как и оператор if, соз-дают простое разветвление, но в отличие от операторов if они предназ-начены для многократного выполнения одного и того же вычислительного процесса (S1;S2;...Sn).

Отметим, что организация цикла на рис. 1.11 соответствует опера-тору repeat..until для первого варианта СА и оператору while..do - для второго (в обоих вариантах со встроенным счётчиком).

Под термином организация цикла понимается правильное выпол-нение начала цикла, его завершения и собственно тела цикла.

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

При продумывании реализации тела цикла необходимо понять, ка-кие операторы не зависят от параметра цикла, и вынести их из цикла либо обозначить простой переменной, что сократит время выполнения алго-ритма. Если переменная X[I], зависящая от параметра цикла I, встре-чается в теле цикла более двух раз, то имеет смысл переобозначить её (например, Y:=X[I]), с тем чтобы не тратить время (кроме первого раза!) на вычисление адреса этой переменной в оперативной памяти; при выходе из итерации (цикла) следует вернуться к старому обозначению. Важно обнаружить и использовать рекуррентные связи между переменными.

При организации завершения цикла необходимо решить вопрос о том, каким должен быть выход из цикла (когда и как: с использованием предусловия или постусловия)? При этом должно быть гарантировано, что для встроенного счётчика все итерации имеют место. Установить, что выход из цикла осуществляется с нужными значениями параметра цикла. Разобраться, с какими значениями переменных циклический алгоритм заканчивает работу, точнее, надо так организовать цикл, чтобы это были нужные для следующего фрагмента СА значения.

Стыковка вложенных циклов предполагает передачу переменных и параметров, их переобозначение, вспомогательные вычисления (напри-мер, начальных значений параметров внутреннего цикла) и т. д.

Ошибки в организации цикла связаны обычно с неправильным выполнением начала цикла или его конца; именно этим моментам и следует уделить особое внимание.

Обычно для проверки правильности организации цикла рассмат-ривают вычислительный процесс по шагам, каждому из которых соответ-ствует своё значение параметра цикла; это можно сделать как на бумаге, так и на компьютере. Операторы тела цикла выполняют пошагово, причём в случае использования бумаги принимаются следующие упрощения: малое число повторов, данные только целого типа, количество варьиру-емых данных уменьшается до предела, после которого задача теряет смысл, и т.п. Эти упрощения можно сделать при глубоком понимании сути задачи. На рис. 1.11,в приведен образец анализа правильности организа-ции цикла (верификация алгоритма).

Соседние файлы в папке Основаная часть