Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ситкин. Информатика. Программирование в DELPHI

.pdf
Скачиваний:
142
Добавлен:
18.07.2019
Размер:
1.49 Mб
Скачать

Реализуем разработанный алгоритм в проекте. Для ввода значений a, b и h вынесем на форму три компонента Edit, а для пояснений к ним три Label. Для вывода результатов разместим на форме четвёр-

тый компонент Label, для которого следует установить значение True свойства AutoSize (автоподбор размера по содержимому), т.к. заранее неизвестно, сколько значений будет выведено в компонент, поскольку это будет определяться введёнными пользователем размерами диапазона и шага. Расчёт и вывод значений свяжем с событием Button1Click.

procedure TForm1.Button1Click(Sender: TObject); var a, b, h, x, y:real;

begin a:=StrToFloat(Edit1.Text);

b:=StrToFloat(Edit2.Text);

h:=StrToFloat(Edit3.Text);

x:=a; //начальное значение х

while x<=b do

begin //начало тела цикла

if x<=0 then y:=sqr(x) else y:=x; Рис. 7.3

Label4.Caption:= Label4.Caption + #13 +

+ 'x=' + FloatToStr(x) + #9 + 'y=' + FloatToStr(y);

вывод в Label значений предыдущей итерации + перевод строки и добавление значений х и y текущей итерации, т.е. накопление таблицы с каждой итерацией

x:=x+h; //увеличение значения х на шаг end; //конец тела цикла

end; //конец процедуры

В случае ввода пользователем h 0 или a b цикл не сможет за-

вершиться произойдёт «зацикливание», что нужно предотвратить.

81

Оператор цикла с параметром (со счётчиком)

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

повторений известно заранее. Он имеет вид

for i:=a1 to a2 do оператор S

где for, to, do служебные слова; i параметр (счётчик); a1 и a2

начальное и конечное значение счётчика; оператор S тело цикла.

Счётчик последовательно принимает значения от a1 до a2 с шагом плюс один, причём a1 должно быть меньше или равно a2. Реализуемая схема представлена на рис. 7.4 а.

Возможен другой вид счётного оператора

for i:=a1 downto a2 do оператор S

здесь счётчик последовательно принимает значения от a1 до a2 с ша-

гом минус один, причём a1

должно быть больше или равно a2. Реали-

зуемая схема представлена на рис. 7.4 б.

 

 

 

 

 

 

В обоих случаях значения i, a1 и a2

должны быть порядкового

типа. Оператор S выполняется один раз для каждого значения i.

 

 

 

 

 

 

 

 

 

 

 

i = a1

 

i = a1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

нет

 

 

нет

 

нет

 

 

 

 

 

 

 

i = a1

.. a2

 

i a2

i a2

 

 

 

да

да

 

 

да

 

 

 

оператор S

 

оператор S

 

 

 

оператор S

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i = i + 1

 

i = i 1

 

 

 

а

б

в

 

 

Рис. 7.4

 

82

Иногда работу счётного оператора любого вида на схеме изоб-

ражают упрощённо (рис. 7.4 в).

 

 

 

 

 

 

Пример 7.2

 

 

 

 

 

 

 

 

 

 

Разработаем алгоритм и проект для вычисления суммы

10

 

ln(kx)

 

ln(2x)

 

ln(3x)

 

ln(10x)

 

S

k

2

 

ln x

4

 

9

...

100

.

k 1

 

 

 

 

 

 

начало

 

 

 

 

Формула для вычисления k-го слагаемого

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

данной суммы ak

ln(kx) . Блок-схема предлага-

n = 10

 

 

 

 

 

 

 

k 2

 

 

 

ввод x

 

 

 

емого алгоритма представлена на рис. 7.5.

 

 

 

 

 

 

 

 

Верхний предел суммирования задан как кон-

S = 0; k = 1

 

 

 

станта n=10. После ввода x задаются начальные

 

 

 

 

 

нет

 

значения суммы S=0 и номера слагаемого k=1,

k n

 

 

 

 

 

 

 

 

 

 

 

 

которое в ходе циклического процесса должно

 

 

 

 

да

 

 

 

изменяться в диапазоне 1..n. В теле цикла для

 

 

 

 

a=ln(k·x)/k2

 

 

 

каждого из них вычисляется значение текущего

 

 

 

 

(k-го) слагаемого, которое прибавляется к

S = S + a

 

 

 

накапливаемой в цикле частичной сумме S. При

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

этом значения a и S предыдущей итерации «за-

k = k + 1

 

 

 

тираются». После этого, увеличив k на единицу,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

переходим к номеру следующего слагаемого,

 

 

 

 

возвращаемся к началу цикла, проверяя, не пре-

 

 

 

 

высил ли номер слагаемого число n. Если не

вывод S

 

 

 

превысил, то циклический процесс продолжает-

 

 

 

 

конец

 

 

 

ся, в противном случае он заканчивается, и вы-

 

 

 

водится итоговая сумма n слагаемых.

 

Рис. 7.5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

83

 

 

 

 

 

Число повторений известно заранее, и с каждой итерацией зна-

чение k надо увеличивать на единицу используем оператор for.

procedure TForm1.Button1Click(Sender: TObject);

const n=10;

var a, x, S:real;

k:byte; //счётчик счётного оператора цикла, должен быть целого типа

begin

x:=StrToFloat(Edit1.Text); //при x 0 ошибка выполнения

S:=0; //нач. знач. суммы, чтобы было к чему прибавлять на первой итерации for k:=1 to n do //нач. (и конеч.) знач. номера слагаемого устанавл-ся в for

begin //начало тела цикла

a:=ln(x*k)/sqr(k); //вычисление текущего слагаемого на k-ой итерации

S:=S+a; //добавление слагаемого k-ой итерации к накапливаемой сумме end; //конец тела цикла; оператор for сам увеличит k на единицу

Label2.Caption:='S='+FloatToStr(S); //вывод накопленной суммы

end; //конец процедуры

Пример 7.3

Разработаем алгоритм и проект для вычисления суммы

10

xk

 

 

 

x

 

 

x2

 

 

x3

 

 

x10

 

S

 

 

 

 

 

 

 

 

 

 

 

 

 

 

...

 

 

 

.

(sin(2x))

k 1

sin

2

(2x)

sin

3

(2x)

sin

4

(2x)

sin

11

(2x)

k 1

 

 

 

 

 

 

 

 

 

 

Формула для вычисления k-го слагаемого данной суммы имеет вид

ak

xk

 

, в принципе возможен алгоритм, идентичный реше-

(sin(2x))

k 1

 

 

 

нию предыдущей задачи. Однако в данном случае рациональнее ис-

пользовать для расчёта k-го слагаемого рекуррентное соотношение,

связывающее текущее слагаемое с предыдущим

84

n = 10
ввод x
a=x/sin2(2x)
начало

 

a

 

 

 

xk

 

 

xk 1

 

xk (sin(2x))k

 

 

x

 

 

 

k

 

 

:

 

 

 

 

,

 

a

 

 

(sin(2x))k 1

(sin(2x))k

xk 1 (sin(2x))k 1

sin(2x)

 

 

k 1

 

 

 

 

 

 

 

 

 

 

 

 

откуда ak

ak 1

x

.

Таким образом каждое

слагаемое

суммы,

 

sin(2x)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

начиная со второго, определяется через предыдущее, домноженное на рекуррентное соотношение. Такой способ поз-

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

Первое слагаемое вычислим по формуле

S = a; k = 2

 

 

a1

 

x

 

; S1 = a1 эти значения (они соот-

 

 

 

 

 

 

 

 

sin

2

(2x)

 

 

 

 

 

 

 

 

 

ветствуют k=1) нужно будет задать до входа в

k n

нет

 

 

 

 

 

 

 

 

цикл для начала счёта по ним. Номер слагаемого

 

 

 

 

 

да

 

 

k в ходе циклического процесса должен изме-

 

 

 

a= ax/sin(2x)

 

 

 

 

няться в диапазоне 2..n. С двух, т.к. для k=1 зна-

 

 

 

 

 

 

чения слагаемого a и суммы S будут определены

 

 

 

S = S + a

 

 

уже до входа в цикл. В теле цикла будет опреде-

 

 

 

ляться текущее слагаемое через слагаемое, вы-

 

 

 

 

 

 

численное на предыдущей итерации, «затирая»

k = k + 1

 

 

 

 

 

 

 

 

 

 

 

 

 

его, и добавляться к сумме, найденной также на

 

 

 

предыдущей итерации, получая новое, текущее,

вывод S

 

 

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

 

 

 

 

 

 

 

 

 

 

 

к следующему номеру слагаемого. Когда k пре-

конец

 

 

высит

n,

цикл завершится, будет выведена

 

 

 

 

 

 

 

 

накопленная сумма (рис. 7.6).

Рис. 7.6

85

procedure TForm1.Button1Click(Sender: TObject);

const n=10;

var a, x, S:real;

k:byte; //счётчик счётного оператора цикла, должен быть целого типа

begin

 

 

x:=StrToFloat(Edit1.Text); //при x = 0 будет ошибка выполнения

a:=x/sqr(sin(2*x)); S:=a; //вычисление начальных значений до тела цикла

for k:=2 to n do

//нач. (и конеч.) знач. номера слагаемого устанавл-ся в for

begin //начало тела цикла

a:=a*x/sin(2*x); //выч-е тек-го слаг. через самого себя предыдущ. итерации

S:=S+a; //добавление слагаемого k-ой итерации к накапливаемой сумме

end; //конец тела цикла; оператор for сам увеличит k на единицу

Label2.Caption:='S='+FloatToStr(S); //вывод накопленной суммы

end; //конец процедуры

 

Оператор цикла с последующим условием

 

Этот оператор обычно используется когда число повторений за-

ранее не известно, а определяется в ходе циклического процесса

 

 

repeat оператор S until условие

здесь repeat, until служебные слова; оператор S тело цикла;

 

 

условие переменная или выражение логиче-

 

 

ского типа. Блок-схема алгоритма, реализуемого

 

оператор S

оператором цикла с постусловием, представлена

 

 

 

 

на рис. 7.7. Оператор S выполняется до тех пор,

нет

условие

пока условие впервые не примет значение True.

 

 

 

 

да

Оператор S выполняется как минимум один раз.

 

Рис. 7.7

 

 

 

86

Пример 7.4

Разработаем алгоритм и проект для вычисления суммы

 

x

k

 

x

2

 

x

3

 

x

k

 

S

 

1 x

 

 

 

...

 

...

 

 

 

 

 

 

 

 

k 0

k!

2

6

 

k!

 

где k! = 1·2·3·...·(k 1k. Напомним, что данная сумма равна ex.

Сумма содержит бесконечное число слагаемых. Но каждое следую-

щее меньше предшествующего, стремится к нулю и всё меньший

 

 

 

начало

вклад вносит в сумму. Поэтому, начиная с некото-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

рого слагаемого, отбросим остальные. Будем по-

 

 

 

ввод x и

лагать, что точность вычисления суммы достаточ-

 

 

 

точн.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

на, если отношение очередного слагаемого к сум-

 

 

 

a = 1; k = 0;

ме всех предыдущих слагаемых по модулю мень-

 

 

 

S = 0

ше числа 0, остальные слагаемые можно не учи-

 

 

 

 

 

 

 

 

 

 

 

 

тывать. Однако заранее нельзя определить сколь-

 

 

 

S = S + a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ко слагаемых войдёт в сумму, сформулировано

 

 

 

 

только условие завершения циклического процес-

 

 

 

k = k + 1

 

 

 

са. Поэтому следует использовать оператор цикла

 

 

 

 

 

 

 

 

с постусловием для реализации алгоритма. Выве-

 

 

 

 

 

 

 

a = ax/k

 

 

 

дем рекуррентное соотношение

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a

k

 

xk

:

xk 1

 

 

 

xk (k 1)!

 

x

ak ak 1

x

.

 

 

 

 

 

 

 

нет

 

 

 

 

 

(k 1)!

 

k 1

(k 1)! k

 

 

 

 

 

|a/S|

 

ak 1

k!

 

 

x

 

 

k

 

k

 

 

 

 

 

 

 

 

 

 

 

 

 

 

да

В цикле (рис.7. 8) определяется значение текущего

 

 

 

вывод S

слагаемого по рекуррентной формуле, если оно не

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

удовлетворяет условию точности, то осуществля-

 

 

 

конец

ется переход к новой итерации, где в её начале это

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 7.8

слагаемое добавляется к сумме. В противном слу-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

87

чае происходит выход из цикла и вывод накопленной суммы без сла-

гаемого, вычисленного на последней итерации, т.к. оно уже удовле-

творило условию |ak/Sk-1| . До входа в цикл следует задать началь-

ные значения a = 1 (значение первого слагаемого), k = 0 (номер перво-

го слагаемого), S = 0 (чтобы получить S = a =1 на первой итерации). procedure TForm1.Button1Click(Sender: TObject);

var x, e, a, S:real; k:byte;

begin

x:=StrToFloat(Edit1.Text);

e:=StrToFloat(Edit2.Text); //точность должна быть положительной a:=1; k:=0; S:=0; //присвоение начальных значений до тела цикла repeat //начало тела цикла

S:=S+a; //добавление слагаемого к накапливаемой сумме k:=k+1; //переход к следующему номеру слагаемого

a:=a*x/k; //вычисление текущего слагаемого по рекуррентной формуле until abs(a/S)<=e; //проверка условия выхода из тела цикла

Label3.Caption:='S='+FloatTostrF(S,ffFixed,10,5); //вывод суммы

Label4.Caption:='слагаемых в сумме '+IntToStr(k); //вывод числа слаг.

Label5.Caption:='альтерн. знач. '+FloatToStr(exp(x)); //необязательно

end;

На рис. 7.9 представлены примеры работы приложения с расчё-

том суммы при трёх значениях точности и контрольным значением.

Рис. 7.9

88

Задание

I. Разработать алгоритм вычисления значений x и y параметри-

ческой функции для значений параметра t от a до b с шагом h и реа-

лизовать его в проекте

 

m

 

 

mt

 

 

 

 

 

 

 

 

 

 

x

 

 

 

x

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2

 

 

 

3

 

 

 

 

2

 

 

 

3

 

 

 

 

t 1

 

t

 

1

 

 

2t

 

x 2cos t

 

x cos(t 2)

 

 

x t

 

 

 

1.

 

m

2.

mt

2

 

3.

 

 

 

4.

 

y 2sin t

5.

 

y cos(t 1)

y

 

y

 

 

 

 

 

2t

 

 

 

 

 

2

 

 

 

 

 

 

 

y t

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t(t 1)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t

3

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

x m(t sin t) 6. y m(1 cos t)

 

 

e

t

e

t

 

 

 

 

 

 

 

 

 

 

 

 

 

x

 

 

 

t

 

 

 

 

 

 

 

 

x t sin t cos t

 

x m cos t

 

 

 

 

2

 

 

 

 

7.

 

e

t

e

t

8.

 

9.

 

 

 

 

 

 

 

y sin t t cos t

 

y msin t

 

y

 

 

 

 

 

1

 

 

 

 

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

II. Разработать алгоритм вычисления конечной суммы или произведе-

ния и реализовать его в проекте

10

 

sin(kx)

1.

 

 

k 1

 

 

k

10

 

e

xi

6.

 

 

 

(i 2)!

i 1

10

(sin x)k

5

 

xk 5

 

 

 

10

xk

 

10

 

cos(kx)

2.

 

 

 

3.

 

 

 

 

 

4.

 

 

 

5.

 

 

 

 

 

k!

 

 

 

 

 

 

 

k!

 

k

2

k 1

 

 

k 5 (k 7)!

 

k 1

 

k 3

 

 

10

(x 1)

i 1

30

e

x / k

e

x / k

 

12

 

 

x

2

 

7.

 

 

8.

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(i 2)!

 

(k 2)4

 

 

 

 

 

 

 

9.

i

 

 

i 1

 

 

 

k 1

 

 

 

 

 

 

i 2

 

 

 

 

 

 

 

III. Разработать алгоритм вычисления бесконечной суммы с точно-

стью 0 и реализовать его в проекте. Проанализировать значение суммы и числа слагаемых в зависимости от значения точности

 

x

2i 1

 

| cos(ix) |

1.

 

 

2.

(2i 1)!

i 1

i 0

i 2

sin 2 (ix) 3. i3 1

i 1

 

| x

|

 

( 1)

i

x

2i

4.

5.

 

 

2

 

(2i)!

 

i 1

i

 

i 0

 

 

sin((2k 1)x)

 

k

cos((2k 1)x)

 

 

i

 

 

2k 1

6.

7.

( 1)

 

8.

x

 

 

9.

x

 

2k 1

 

 

2k 1

i i!

2k 1

k 0

k 0

 

i 1

k 0

 

0 x

 

/ 4 x

 

 

 

 

 

x

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Предусмотреть в проектах конструкции контроля вводимых ис-

ходных данных на корректность, в т.ч. возможность «зацикливания».

89

Содержание отчёта

цель работы и задание;

для каждого из трёх заданий:

блок-схема алгоритма решения;

текст модуля проекта;

пример работы приложения с указанием компонентов;

тестирование приложения альтернативным расчётом;

выводы по работе.

Контрольные вопросы

1.Что такое повторяющийся алгоритм?

2.Каков синтаксис операторов цикла, какие конструкции реализует каждый из них и в каких ситуациях обычно используется?

3.Можно ли использовать логическую константу в условии входа или выхода из цикла, почему?

4.Опишите способы вычисления конечных и бесконечных сумм.

5.Почему в теле счётного оператора цикла не пишут оператор увели-

чения (или уменьшения) счётчика на единицу?

6.Что такое «зацикливание»?

7.Какие значения получат переменные x и y?

S:=0; n:=1;

S:=0; n:=1;

S:=0; n:=1;

S:=0; n:=1;

while n 3 do

while n=3 do

repeat

repeat

begin

begin

S:=S+n;

S:=S+n;

S:=S+n;

S:=S+n;

n:=n+1;

n:=n+1;

n:=n+1;

n:=n+1;

until n 3;

until n 3;

end;

end;

x:=S; y:=n;

x:=S; y:=n;

x:=S; y:=n;

x:=S; y:=n;

 

 

 

 

 

 

90