Пример 4.6.1-3. Написать процедуры вывода, которые могут использоваться в алгоритмах итеративных циклических структур.



Тема 4.6

Программирование алгоритмов
итеративных циклических

Структур

Средства программирования

Итеративных циклических структур

 

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

В зависимости от места расположения условия продолжения цикла (или выхода из цикла) итеративные циклические структуры подразделяются на два вида: с предусловием и с постусловием (рис. В.3-10 и рис. В.3-11).

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

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

Необходимо отметить, что логическое выражение (условие) L имеет тот же смысл, что и в Теме 4.4.

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

Рекуррентная формула – это такая формула, которая сводит вычисления n-го члена последовательности к вычислению нескольких предыдущих членов (или, часто, одного предыдущего члена этой последовательности – n-1). В общем случае такая формула имеет вид:
Sn= Sn-1 + Un, где Sn – сумма первых n слагаемых ряда, которая образуется из суммы, полученной на предыдущем шаге Sn-1 и слагаемого Un, полученного на текущем шаге.

Многие числа и функции можно записать с помощью рядов, например, для числа ряд можно записать двумя способами:

 +  +  + . . .

=1  + + . . .

Второй ряд сходится более медленно, т.е. требует большего числа слагаемых для достижения той же точности.

Конструкции, реализующие в VBитеративные циклы с предусловием, могут иметь следующие форматы:

 

Do While L Операторы Тела Цикла [ Exit Do ]Loop Do Until L Операторы Тела Цикла [ Exit Do ]Loop

 

А итеративные циклы с постусловием, имеют следующие форматы:

 

Do Операторы Тела Цикла [ Exit Do ]Loop While L Do Операторы Тела Цикла [ Exit Do ]Loop Until L
Если используется ключевое слово While, то цикл повторяется до тех пор, пока условие L истинно, а если Until– то пока ложно. Таким образом, после ключевого слова While записывается условие продолжения цикла, а после Until – условие завершения цикла (выхода из цикла).

Другими словами, циклы Do…Loopразличаются местом расположения условия, которое помещается либо в заголовке цикла (в первой строке Do…), либо в конце цикла (в последней строке Loop…).

Для досрочного выхода из цикла используется  оператор Exit Do.

Пример 4.6.1-1. Написать процедуру-Function, которая вычисляет произведение натуральных чисел от 1 до n (факториал n!=1*2*3*4*…n).

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

 

Function Pr611(ByVal n As Integer) As Long Dim I As Integer, p As Long p = 1 : I = 0                       Do While I < n                 I = I + 1 : p = p * I        Loop Return p End Function

 

Рис. 4.6.1-1. Программный код процедуры Pr611(),
которая вычисляет факториалn Примера 6.1-1

 

Процедура-Futncion Pr611(), использующая итеративную циклическую структуру с предусловием, представлена на рис. 4.6.1-1.

Цикл Do…Loop в представленной программе будет выполняться до тех пор, пока значение переменной I не достигнет значения n. Здесь логическое условие продолжения цикла (I<n), помещенное после ключевых слов Do While, позволяет проверять его перед началом выполнения первого оператора тела цикла. Если условие продолжения цикла для начальных условий истинно (т.е. равно True),то все операторы цикла будут выполнены. Потом условие I<n будет проверено снова, и так до тех пор, пока условие не станет ложным – False. После этого выполнение операторов в теле цикла будет прекращено, и программа переходит к выполнению оператора, следующего за ключевым словом Loop.

Если, например, по условиям задачи необходимо, чтобы тело цикла выполнилось, по крайней мере, один раз, то в этом случае нужно использовать вторую форму оператора Do…Loop, в которой условие помещается в конце цикла, после ключевых слов Loop While…или Loop Until….

Процедура-Function,реализующая такую структуры цикла, рассмотрена в Примере 4.6.1-2.

 

Пример 4.6.1-2. Написать процедуру-Function, которая вводит натуральное число n, значение которого находится на отрезке [1; 15], с проверкой ввода (т.е. должны выполняться условия n>=1 AND n<=15).

Самой удобной структурой для такой проверки будет структура цикла с постусловием Do…Loop Until. Такой цикл будет повторяться до тех пор, пока это условие равно False. Как только условие станет равно True, т.е. число попадет в границы диапазона, то цикл прекращается.

Процедура-Function Pr612( ) представлена на рис. 4.6.1-2.

 

Function Pr612( ) As Integer Dim n As Integer Do n = vvodInt9("Введите n (1<n<15)", TextBox1) Loop Until n >=1 And n <= 15 Return n End Function

  

Рис. 4.6.1-2. Программный код процедуры Pr612(),
 
которая проверяет введенное значение

Примера 4.6.1-2

 

Пример 4.6.1-3. Написать процедуры вывода, которые могут использоваться в алгоритмах итеративных циклических структур.

Некоторые процедуры ввода и вывода приведены в Теме 4. Остальные процедуры ввода и вывода, которые используются при написании базовых алгоритмов итеративных циклических структур, представлены на
рис. 4.6.1-3 – 4.6.1-4.6.

 

'Процедура вывода значений переменных Integer и Double в TextBox  Sub vivodID11(ByVal n As Integer,ByVal T1 As String _           ByVal a As Double, ByVal T2 As String, _           ByVal T As TextBox)      T.Text = T.Text & T1 & CStr(n) & T2 & CStr(a) & vbCrLf  End Sub

 

Рис. 4.6.1-3. Программный код процедуры vivodID11()

вывода значений двух переменных типа Integer и Double в TextBox

Примера 4.6.1-3

 

'Процедура вывода целого результата в ListBox Sub vivodIntLs12(ByVal n As Integer, ByRef LB As ListBox) LB.Items.Add(CStr(n)) End Sub

 

Рис. 4.6.1-4. Программный код процедуры vivodIntLs12()

вывода целого результата в ListBox

Примера 4.6.1-3

'Процедура вывода вещественного результата в ListBox Sub vivodDblLs13(ByVal Z As Double, ByRef LB As ListBox) LB.Items.Add(CStr(Z)) End Sub

Рис. 4.6.1-5. Программный код процедуры vivodDblLs13()

вывода вещественного результата в ListBox

Примера 4.6.1-3

'Процедура форматного вывода значений переменных Integer в ТextBox Sub vivodFxn14(ByVal x As Long, ByVal n As Integer, _            ByVal T As TextBox) T.Text = T.Text & Format(x, "0") & Space(8) & _                Format(n, "0") & vbCrLf End Sub

 

Рис. 4.6.1-6. Программный код процедуры vodFxn14()

форматного вывода значений двух переменных типа IntegerвТextBox

Примера 4.6.1-3

 

 

4.6.2. Базовые алгоритмы
итеративных циклических структур
и примеры их программирования

 

Рассмотрим сумму вида S= a1 + a2 + a3 + . . . пусть имеется положительное число ε > 0, называемое точностью вычислений. Во многих задачах точность вычисления суммы S считается достигнутой, когда выполняется одно из следующих условий:

· разность │Si – Si-1│ < ε, где Si – сумма на i–м шаге цикла (т.е. сумма содержит i слагаемых), а Si-1 – сумма на предыдущем шаге;

· разность │ai – ai-1│< ε, где ai – значение слагаемого на i-м шаге, а
ai-1 – на предыдущем шаге цикла;

· значения │Si│ < ε и значение │ai│ < ε.

 

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

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

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

Рассмотрим теперь некоторую последовательность, содержащую бесконечное число членов: a0, a1, a2, a3,…, ai,…, an,… В таких задачах требуется вычислять члены последовательности до тех пор, пока очередной вычисленный член не будет удовлетворять некоторому условию.

Если задано некоторое число ε,условия окончания итерационного процесса могут, например, быть следующими:

· для убывающей последовательности an < ε;

· для возрастающей последовательности an > ε (примеры 4.6.2-1, 4.6.2-3,
4.6.2-5);

· для убывающей знакопеременной последовательности |an| < ε
(
пример 4.6.2-4);

· для некоторых других последовательностей |an+1 -an|<ε (пример 4.6.2-2).

 

Пример 4.6.2-1. Написать процедуру-Function, которая среди последовательности чисел (факториал n! =1*2*3*4* . . . n) находит первое число, большее заданного значения переменной a.

Алгоритм решения данной задачи относится к алгоритмам вычисления членов бесконечных последовательностей (рис.4.6.2-1).

 Этот алгоритм использует итеративный цикл с предусловием и реализуется с помощью конструкции Do While ... Loop.

Для решения данной задачи проведем формализацию. Для этого введем следующие обозначения: b – очередной член бесконечной последовательности; n – номер этого члена, который в данной задаче совпадает со значением знаменателя дроби, добавляемой к предыдущему члену для получения значения очередного члена последовательности. Таким образом, итерационная формула вычисления очередного члена последовательности будет иметь следующий вид: (т.е. должны выполняться условия n>=1 AND n<=15), где n – номер члена.


 

Function Pr621(ByVal a As Double)As Double Dim b As Double Dim n As Integer b = 1 n = 1                                                                          Do While b <= a n = n + 1    b = b + 1 / n Loop Return b End Function

Рис. 4.6.2-1.Схема алгоритма и программный код процедуры Pr621(),
которая среди последовательности чисел находит первое число,
большее заданного значения, используя оператор Do While...Loop

Примера 4.6.2-1

 

Процедура-функция Pr621()может быть вызвана из любой другой процедуры или из модуля формы, например, как показано на рис. 4.6.2-2.

 

Dim aa, bb As Double aa = vvodDbl2("Введите значение a=", TextBox1 ) bb = Pr621(aa) vivodDbl1(bb,TextBox2)

 

Рис. 4.6.2-2. Пример обращения к процедуре Pr621()

 


 

Решение данного примера может быть реализовано также с использованием конструкции Do Until…Loop(рис. 4.6.2-3), а цикл с предусловием можно заменить на цикл с постусловием и соответствующим ему изменением настройки цикла (рис. 4.6.2-4).

 

Function Pr623(ByVal a As Double) As Double Dim b As Double Dim n As Integer  b = 1  n = 1                                                                           Do Until b > a n = n + 1   b = b + 1 / n  Loop  Return b End Function  

 

Рис. 4.6.2-3. Схема алгоритма и программный код процедуры Pr621(),
которая среди последовательности чисел находит первое число,
большее заданного значения, и, используя оператор Do Until…Loop

Примера 4.6.2-1

 

Изменим в цикле условие продолжения выполнения цикла
(на рис. 4.6.2-1 заменим условие b <= a на условие b > a), т.е. будем проводить вычисления членов последовательности до тех пор, пока не встретится член, больший заданного числа. Заменим условие b <= a на условие b > a.

Тогда алгоритм и функция будут выглядеть, как на рис.4.6.2-3.

Если вычисление членов последовательности проводится в теле цикла, начиная с первого, то алгоритм и процедура-функция примут вид, показанный на рис 4.6.2-4.

 

Function P624(ByVal a As Double) _                  As Double Dim b As Double Dim n As Integer b = 0 n = 0                                                                          Do n = n + 1   b = b + 1 / n Loop Until b > a Return b End Function    

 

Рис. 4.6.2-4. Схема алгоритма и программный код процедуры Pr624(),
которая среди последовательности чисел находит первое число,
большее заданного значения, используя, оператор Do…Loop Until

Примера 4.6.2-1

Мы получили структуру итеративного цикла с постусловием, изменив настройку цикла: n = 0, b = 0. В данном случае условием окончания вычислительного процесса служит значение True логического выражения
b > a, а продолжением – значение False (конструкция Do…Loop Until).

Изменив условие на b <= a, получим конструкцию цикла с
Do…Loop Wile.

Следовательно, задача может быть решена с использованием как цикла с предусловием, так и цикла с постусловием.

 

Пример 4.6.1-2. Написать процедуру-Function, которая вводит натуральное число n, значение которого находится на отрезке [1;15], с проверкой ввода (т.е. должны выполняться условия n>=1 AND n<=15).

Вос­пользуемся известной итерационной формулой, где i=0, 1, 2,...; x0=0.Следует закончить итеративный процесс, как только |xi+1-xi| станет меньше ε=10-4.

Для решения этой задачи необходимо из очередного приближения вычисленного корня xi+1 вычитать значение предыдущего приближения корня xi. Для этого при каждом повторении цикла перед вычислением очередного значения корня xсохраняем в переменной a текущее значение x (оно становится предыдущим). Цикл прекращаем, если разность между a (т.е. xi) и x (т.е. xi+1) станет меньше e=10-4.

 

Алгоритм решения данной задачи относится к итерационным алгоритмам (рис. 4.6.2-5) и может быть реализован, например, с помощью конструкции Do ... Loop Until c постусловием.

 

Function P625( ) As Double Dim a, x, d As Double x = 0 d = 1E-4 Do   a = x   x = -Exp(a) Loop Until Abs(x - a) < d Return x End Function

 

Рис. 4.6.2-5. Схема алгоритма и программный код процедуры Pr625(),

которая реализует ввод данных с их проверкой

Примера 4.6.2-2

Процедура-Function Pr625()может быть вызвана из любой другой процедуры или из модуля формы, например, как показано на рис. 4.6.2-4.6.

 

Dim xx As Double  xx = Pr625()  vivodDbl1(xx, TextBox1)

 

Рис. 4.6.2-6. Пример обращения к процедуре Pr625()

Примера 4.6.2-2

Пример 4.6.2-3. Задана возрастающая последовательность       

Требуется написать программу, которая вычисляет все члены последовательности, до тех пор, пока значение очередного члена не превысит некоторое заданное число d, например, (3 <d <100).

В нашей задаче для вычисления любого члена последовательности можно воспользоваться формулой, , где n=0, 1, 2,…- номер члена.

В задачах, использующих итеративные алгоритмические структуры, рекомендуется предусмотреть так называемую «страховку от зацикливания», так как иногда условие продолжения цикла может оставаться истинным бесконечно. В данном примере цикл с постусловием будет выполняться не более 100 раз, даже если очередной член последовательности будет оставаться меньше d(рис. 4.6.2-7). Так как вывод в TextBoxчленов последовательности должен происходить в процессе вычисления (внутри цикла), то для решения задачи напишем процедуру-Sub.

 

Sub Pr627(ByVal x As Double, _      ByVal d As Double) Dim n As Integer = 0 Dim a As Double Do а = x^n / 3^n vivodID11(n, "n=",a, "a=", TextBox3) n=n+1 Loop While a <= d And n < 100 End Sub    

 

Рис. 4.6.2-7. Схема алгоритма и программный код процедуры Pr627(),

которая вычисляет члены последовательности
до выполнения определенных условий

Примера 4.6.2-3

Процедура-Sub Pr627( ) может быть вызвана из любой другой процедуры или из модуля формы, например, как показано на рис. 4.6.2-8.

 

Dim xx, dd As Double xx = vvodDbl2("Введите значение xx= ", TextBox1) dd = vvodDbl2("Введите значение dd= ", TextBox2) Pr627(xx, dd)

      

Рис. 4.6.2-8. Пример обращения к процедуре Pr627()

Примера 4.6.2-3

Пример 4.6.2-4. Написать процедуру-функцию, которая вычисляет сумму членов знакопеременной убывающей последовательности с заданной точностью ε:   .

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

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

 

Function Pr629(ByVal x As Double,_           ByVal e As Double) As Double Dim a, s As Double Dim n As Integer = 0 a = x – 1 s = 0 Do Until Abs(a) < e Or n > 100    vivodIntLs12(n, ListBox1)    vivodDblLs13(a, ListBox2)    s = s + a    a = -a * (x - 1) / (n + 2)    n = n + 1 Loop Return s End Function  

 

Рис. 4.6.2-9. Схема алгоритма и программный код процедуры Pr629(),

которая вычисляет сумму членов знакопеременной убывающей последовательности с точностью ε

Примера 4.6.2-4

 

Приведем вывод рекуррентной формулы для заданного в примере ряда. Формула для n-го члена приведена в задании:

Приведем вывод рекуррентной формулы для заданного в примере ряда. Формула для n-го члена приведена в задании:

 тогда формула n+1 члена

Разделив an+1 член на an, получим выражение для q

Таким образом, рекуррентная формула для данного ряда:

Выбор начального значения номера члена ряда (n) для нашего случая будет n=0, так как при подстановке этого значения в формулу n-го члена ряда

мы получим значение первого члена, равного x-1 или a0=x-1.

Схема алгоритма и процедура-Function приведены на рис. 4.6.2-9, причем алгоритм этот с предусловием, в котором предусмотрено выполнение цикла не более 100 раз, чтобы избежать зацикливания.

Процедура-Function Pr629( ) может быть вызвана из любой другой процедуры или из модуля формы, например, как показано на рис. 4.6.2-10.

 

Dim xx, ee, ss As Double xx=vvodDbl2("Введите значение xx=", TextBox1) ee=vvodDbl2("Введите значение ee=", TextBox2) ss = Pr629(xx, ee) vivodDbl1(ss, TextBox3)

 

Рис. 4.6.2-10. Пример обращения к процедуре Pr629()

Примера 4.6.2-4

 

Приведем вывод рекуррентной формулы для заданного в примере ряда. Формула для n-го члена приведена в задании:

 тогда формула n+1 члена

Разделив an+1 член на an, получим выражение для q

Таким образом, рекуррентная формула для данного ряда:

Выбор начального значения номера члена ряда (n) для нашего случая будет n=0, так как при подстановке этого значения в формулу n-го члена ряда

мы получим значение первого члена, равного x-1 или a0=x-1.

 

Function P6211(ByVal x Double, _ ByVal e As Double) As Double Dim a, s As Double Dim n As Integer = 0 a = x – 1 s = 0 Do Until Abs(a) < e Or n > 100    vivodIntLs12(n,ListBox1)    vivodDblLs13(a,ListBox2)    s = s + a    n = n + 1    a =- a * (x - 1) / (n + 1) Loop Return s End Function

Рис. 4.6.2-11. Схема алгоритма и программный код процедуры Pr6211(),

которая вычисляет сумму членов знакопеременной убывающей последовательности с точностью ε

Примера 4.6.2-4

Схема алгоритма и код процедуры-функции приведены на
рис. 4.6.2-11. В этом случае, в отличие от предыдущего, увеличивать n (n=n+1) следует до, а не после вычисления очередного члена ряда.

 


Дата добавления: 2018-05-09; просмотров: 498; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!