|
|
Назад
Раздел "Программирование"
Практическая работа "Циклы"
Цель: рассмотреть циклы с предусловием While… do и с постусловием Repeat… until на примере решения задач с использованием рекуррентных соотношений.
Введение. Циклы While… do и Repeat… until используются в целом классе задач, когда повторные вычисления заканчиваются по заданному наперед условию. Например, с помощью этих циклов рассчитывают бесконечные асимптотические ряды для тригонометрических функций, трансцендентные числа PI=3,1415… и основание натурального логарифма e=2,72…
Задача о рассеянном джентльмене. Некто отправился на работу из дома (пункт А) в офис (пункт B). Расстояние между домом и офисом равно 1 км. Пройдя половину пути, джентльмен вспомнил, что не попрощался с семьей, повернул назад и прошел третью часть расстояния и, боясь опоздать на работу, снова повернул и прошел четверть расстояния. Затем снова повернул и прошел 1/5 расстояния и т.д.
На каком расстоянии от офиса окажется джентльмен, если продолжит свои метания? Провести вычисления расстояния с точностью до 1 см.
Методические пояснения к задаче. Попробуем изобразить схему пути джентльмена, откладывая соответствующие векторы:
Нетрудно видеть, что расстояние, на котором окажется джентльмен от дома, можно записать так:
Sд = 1/2 - 1/3 + 1/4 - 1/5 + 1/6 – 1/7 +… (-1)i+1 /i…
Тогда, с учетом того, что расстояние АВ=1, расстояние расстояние от места работы равно:
S=1-Sд = 1- [1/2 - 1/3 + 1/4 - 1/5 + 1/6 - 1/7 +… (-1)i+1 /i …
Таким образом, в математическом плане необходимо найти сумму гармонического ряда
S= 1-1/2 + 1/3 – 1/4 + 1/5 -… (-1)i+1 /i -…
Суммирование продолжаем, пока абсолютное значение разности сумм, вычисленных на (i+1)-м шаге и i-м шаге, больше наперед заданного малого числа eps , т.е. |S-S1|> eps.
Таким образом, ряд вычисляется приближенно с заданной погрешностью.
Для решения задачи используем цикл While… do
Program harmony_riad;
{Вычисление гармонического ряда};
uses crt;
const eps=0.00001;
var
i: integer;
S,S1 :real;
p: integer;
Begin
clrscr;
s1:=0;{начальное значение для 1-го члена ряда }
s:=1; {суммирование 1-го члена ряда}
i:=1; {начальное значение для 1-го члена ряда }
p:=-1; {знак числа}
while abs(s1-s) > eps do
begin
s1:=s; {запоминаем сумму, вычисленную на предылущем шаге}
i:=i+1; {формирование нечетного числа}
s:=s+p/i; {суммирование знакопеременного ряда}
p:= - p; {смена знака}
end; {while}
writeln('S от офиса=', s:7:5);
readln
End.
Задача. Вычислить квадратный корень целого числа а по рекуррентной формуле Герона
Xi+1=(X i+а/X i)/2 при заданной точности вычисления eps.
Алгоритм вычисления, Зададим x1 - начальное значение корня из числа а.
Например, X1= a/2.
Тогда каждое следующее приближение вычисляется через предыдущее:
Х2=(X1 + а/X1)/2
Х3=(X2 + а/X2)/2
-----------
Xi+1=(X i + а/X i)/2
Вычисление продолжаем до тех пор, пока разница между Xi+1 и Xi)
станет меньше заданной погрешности вычисления eps .
Для решения задачи используем цикл Repeat… until
program mysqrt;
{Вычисление коpня числа по фоpмуле Герона х=(х+а/х)/2}
Uses Crt;
const eps=0.0001;
var
a:Integer;
x,x1:Real;
Begin
clrScr;
Write('Введите число а=');
Readln(a);
x:=a/2; {начальное значение корня}
Repeat
x1:=x; {запоминаем i-е приближение корня}
x:=(a/x+x)/2; {вычисляем (i+1)-е приближение корня}
until abs(x-x1)
Writeln ('Коpень числа ',a,' pавен ',x);
readln
End.
Задание
1. Отладить программу и переписать листинг программы с комментариями в тетрадь.
2. Изменить начальное значение корня X1, задав его равным 1.
3. Вычислить корень из числа с помощью стандартной функции sqrt(a) и сравнить с приближенно вычисленным. В чем разница?
4. Ввести в программе счетчик n для подсчета количества итераций (шагов) и определить, чему равно n при разных значениях погрешности eps.
Результат записать в табличку:
| eps |
n |
| 0.01 |
... |
| 0.001 |
... |
0.0001 | ... |
Контрольные вопросы
Влияет ли выбор начального значения x1 на результат вычислений?
Как влияет значение eps на результат вычислений?
Можно ли использовать для решения этой задачи цикл While… do? Если да, то что изменится?
Счетчик n:=n+1 можно разместить на входе или на выходе из тела цикла. Какими следует задать начальные значения для n, чтобы избежать ошибки в подсчете количества итераций?
|
ТЕСT1
Простые циклы
Задача 1. Написать программу для вычисления n-й степени числа X. Вычисление описать каждым из трех вариантов оператора цикла: For... to...do, While… do, Repeat… until.
Задача 2. Напишите программу для вычисления n-й степени числа X, задав n как целое.
Задача 3.
Итальянский математик Леонардо Фибоначчи, решая задачу о размножении кроликов, описал числовую последовательность вида:
1 1 2 3 5 8 13 21 ...,
названную впоследствие его именем. Нетрудно видеть, что F1=1, F2=1,
а каждое i-е число равно сумме двух предыдущих :
Fi=Fi-1 + Fi-2
Вычисляя величину отношения больших чисел Фибоначчи V=Fi+1/Fi),
можно приблизительно определить константанту золотого сечения. Проведите вычисления с точностью eps=0.001.
Задача 4. Вычислив асимптотический ряд
S= 1-1/3 +1/5 -1/7 + 1/9 - … (-1)i+1 (1/(2i+1))...
с точностью eps=0.0001 , вы узнаете, чему равно число PI = 4*S
Замечание Здесь удобно использовать такую формулу для нечетного числа:
i:=i+2 (i=1, 2, 3...).
Задача 5. Для заданного x вычислить порядковый номер первого из чисел
sin(x), sin(sin(x)), sin(sin(sin(x))), ... , величина которого по модулю меньше 0,0001.
Задача 6. Дана последовательность вещественных чисел, заканчивающаяся 0. Определить является ли она последовательностью вида
An=An-1/(3n), где n=2,3...
Задачи для разминки
1. Чему будет равно значение переменной х после выполнения фрагмента программы?
a:=0;
for i:=1 to 5 do
a:=a+1;
2. Чему будет равно значение переменной f после выполнения фрагмента программы?
f:=2; x:=0;
for i:=1 to 5 do
begin
x:=x+1;
f:= f * x;
end;
3. Чему будет равно значение переменной S после выполнения фрагмента программы?
a:=0; S:=0;
while a<= 3 do
begin
S:= S + a;
a:=a+2;
end;
4. Чему будет равно значение переменной S после выполнения фрагмента программы?
S:=1; a:=0;
while a> 0 do
begin
S:= S * 2;
a:=a-1;
end;
5. Чему будет равно значение переменной S после выполнения фрагмента программы?
a:=0; S:=0;
repeat
S:= S + a;
a:=a+2;
until a>2 ;
|