Добавлен: 15.11.2018
Просмотров: 5615
Скачиваний: 36
Обозначим вычисляемую сумму через S, счетчик ряда — I, очередной член ряда — С.
Вычисление суммы ряда — это цикл с известным (заданным) числом повторений (от 1 до К), в котором не только вычисляются текущие значения членов ряда, но и накапливается их сумма путем прибавления полученного значения члена ряда к сумме предыдущих. В нашем примере формулой для накопления суммы нескольких слагаемых является формула Si := Si-1 + Сi. Таким образом, значению суммы на i-м шаге присваивается значение частичной суммы на предыдущем шаге плюс слагаемое Сi. Поскольку надобности в запоминании значений всех промежуточных сумм и членов ряда нет, в качестве S нужно использовать простую переменную и накопление суммы вести по формуле S:=S+С.
До ввода в цикл вычисления суммы S его надо подготовить, т.е. присвоить S нулевое значение (“обнулить”) — S = 0, а перед накапливанием вычислить очередное слагаемое С — очередной член ряда.
Будет совершенно нерационально использовать для вычисления очередного члена ряда общую формулу, указанную в постановке задачи. Действительно, например, для 5-го номера получим:
C5 = + , а для шестого – С6 = -.
Отсюда следует, что для вычисления очередного слагаемого можно использовать оператор присваивания:
C := -С*I/X.
Начальное значение переменной С надо определить до входа в цикл: С = -1.
После выхода из цикла необходимо вывести полученные результаты. Форма вывода результатов в постановке задачи не определена, выбираем ее сами, например, в виде:
Результаты вычислений
Число членов ряда: * * *
Аргумент ряда: **.**
Сумма ряда: ****.***
Этот макет реализуется необходимой последовательностью операторов вывода. Таким образом мы достаточно детализировали алгоритм решения задачи.
Текст программы
PROGRAM Prim110;
{Вычисление суммы ряда }
VAR X, C, S : REAL;
K, I : INTEGER;
{К—число членов ряда }
{X — аргумент }
{С—очередной член ряда }
{I—номер члена ряда }
{S - вычисляется сумма }
BEGIN
{Этап ввода исходных данных }
WRITE(‘Число членов ряда-‘);
READLN(К);
WRITE(‘Аргумент (больше 0)');
READLN( Х);
{Этап вычислений }
{Подготовка цикла}
S:=0;
C:= -1;
FOR I:=1 TO K DO
BEGIN
{Вычисление значения члена ряда}
С:= -C*I/X;
{Накопление суммы}
S:=S+C;
END;
{Этап вывода }
WRITELN(‘Результаты вычислений');
WRITELN(‘Число членов ряда: ‘ ,К:3);
WRITELN(‘Аргумент ряда: ‘, Х:5:2);
WRITELN(‘Сумма ряда: ‘, S:7:3);
END.
Формальное исполнение программы
Принимаем К=4. Значение аргумента можно не конкретизировать, записывая каждый раз выражение для вычисления слагаемого. Результаты формального исполнения:
Подготовка: S = 0, С = -1
i = l c = +l/x , s = + l/x;
i = 2 c= -l · 2/x2, s = +l /x – l · 2/x2;
i = 3 с = +1 · 2 · 3/х3,
s = +l/x – l · 2/x2 + 1 · 2 · 3/x3;
i = 4 с = -1 · 2 · 3 · 4/х4,
s = +1/x – 1 · 2/х2 + 1 · 2 · 3/х3 – 1 · 2 · 3 · 4/x4.
Результаты, полученные при формальном исполнении программы, свидетельствуют о правильности составленного алгоритма.
Пример 1.11. Вычислить факториал p= n!, (n! = 1 · 2 · 3 … n) при n = 6.
Решение.
Вариант программы будет иметь вид:
PROGRAM Prim111;
VAR
N, P, I : INTEGER;
BEGIN
N:=6;
P:=1;
For I:=1 TO N DO
P:=P*I;
WRITELN(‘P=’,P)
End.
Пример 1.12. Найти и напечатать все делители натурального числа N.
Решение.
Перед составлением программ по обработке целых чисел необходимо ознакомиться с арифметическими операциями DIV и MOD.
Напомним, что операция DIV является операцией целочисленного деления и выделяет целую часть от деления одного целого числа на другое.
Операция MOD выделяет остаток от деления одного целого числа на другое.
Например:
А:=5 DIV 2;
WRITE(A);
На экране появится «2».
М:=5 MOD 2;
WRITE(M);
На экране появится «1».
Если даны 2 числа А и В, то по определению В является делителем числа А, если А делится на В без остатка.
Минимальное количество делителей у каждого целого числа равно двум — это единица и само число.
Число, имеющее только два делителя, называется простым.
В данном алгоритме делители определяются перебором всех чисел в диапазоне от 2 до N/2. Если заданное число N делится без остатка на какое-либо из этих чисел, то это число будет являться одним из делителей числа N.
Диапазон делителей ограничен сверху величиной N/2, так как ни одно число не делится без остатка на число, большее своей половины.
Вариант программы
PROGRAM Prim112;
TYPE
NATUR = 1 .. MAXINT;
VAR
N : NATUR;
I : INTEGER;
BEGIN
WRITE(‘Введите число‘);
READLN(N);
WRITELN(‘Делители числа’,N, ‘:');
WRITE( 1);
FOR I:=2 TO N DIV 2 DO
IF N MOD I = 0 THEN WRITE( I:5);
WRITELN(N); END.
В приведенной программе делители только выводятся на экран, но не запоминаются. В ряде случаев необходимо запоминать делители в оперативной памяти. Для этого создается одномерный массив, имеющий размерность, достаточную для запоминания всех делителей числа.
Пример 1.13. Ввести с клавиатуры границы диапазона трехзначных натуральных чисел, из которых напечатать только простые. Определить количество таких чисел и их сумму.
Решение.
Обозначим:
А - нижняя граница диапазона;
В - верхняя граница диапазона;
S - сумма простых чисел;
KOL - количество простых чисел;
FL - признак простого числа (0 - простое число, 1 - непростое).
В приведенном алгоритме простые числа определяются перебором всех чисел данного диапазона и вычислением делителя каждого из них (во вложенном цикле FOR I:=...).
Если у числа только два делителя (единица и само число), то число простое (FL=0), если больше, то число непростое (FL=1).
Вариант программы
PROGRAM Prim113;
VAR
A, B, N : 100 ..999;
FL, D, S, KOL : INTEGER;
BEGIN
WRITE(‘Нижняя и верхняя границы диапазона трехзначных чисел‘);
READLN(А, В);
S:=0;
KOL:=0;
FOR N:=A TO В DO
BEGIN
FL:=0;
FOR D:=2 TO N DIV 2 DO
IF N MOD D=0 THEN BEGIN FL:=1; BREAK END;
IF FL=0 THEN BEGIN KOL:=KOL+1; S:=S+N END;
END;
WRITELN(‘Сумма ‘,S,’ и количество простых чисел ’, KOL)
END.
Задача 1.14. В произвольной последовательности N вещественных чисел определить максимальное количество подряд идущих нулей.
Решение.
Обозначим объекты задачи:
N - количество чисел последовательности,
S - счетчик подряд идущих нулей,
МАХ - максимальное количество подряд идущих нулей,
Х - переменная с очередным числом последовательности.
Возможный вариант программы
PROGRAM Prim114;
VAR
N, I, S, MAX : INTEGER;
X : REAL;
BEGIN
WRITE(‘Количество чисел в последовательности’);
READLN(N);
S:=0;
МАХ:=0;
FOR I:=1 ТО N DO
BEGIN
WRITE(‘Значение ‘, I:4, ‘-го числа последовательности ’);
READLN( X);
IF Х=0 THEN S:=S+1
ELSE S:=0;
IF S > MAX THEN MAX:=S
END;
WRITELN(‘Максимальное количество подряд идущих нулей = ', МАХ:4);
END.
Цикл с неизвестным числом повторений
Цикл с неизвестным числом повторений называется также итерационным циклом. В языке Турбо Паскаль имеются два оператора цикла - WHILE и REPEAT, которые используются для организации цикла с неизвестным числом повторений.
Общая форма конструкции, образующей цикл WHILE, имеет вид:
WHILE <выражение> DO <оператор>
Здесь WHILE (пока); DO — ключевые слова языка; <выражение> — логическое выражение, которое определяет условие продолжение цикла. Первая строка (оператор WHILE) конструкции называется заголовком цикла.
<Оператор> образует тело цикла, состоящее из простого или составного оператора.
Выполнение оператора WHILE происходит следующим образом:
1. Вычисляется выражение, указанное в заголовке цикла.
2. Если выражение истинно, то один раз выполняется тело цикла и вновь вычисляется выражение.
3. Пункт 2 повторяется до тех пор, пока выражение истинно.
4. Если выражение ложно, то тело цикла не выполняется, осуществляется выход из цикла, т.е. управление передается оператору, который следует за оператором WHILE.
Общий вид записи оператора REPEAT:
REPEAT <оператор> UNTIL <выражение>
где <оператор> - тело цикла, состоящее из простого или составного оператора; <выражение> - логическое выражение, определяющее окончание цикла.
Выполнение оператора WHILE происходит следующим образом:
-
Выполняется тело цикла.
-
Вычисляется выражение, указанное во фразе UNTIL.
3. Если выражение ложно, то повторяются пп. 1 и 2.
4. Если выражение истинно, то выходим из цикла, т.е. управление передается оператору, который следует за оператором REPEAT.
Из сказанного следует важное правило: операторы тела цикла WHILE и REPEAT должны изменять выражение, указанное в операторе. В противном случае будет иметь место бесконечный цикл, что противоречит определению алгоритма.
В тело итерационного цикла допускается включать другие циклы. Это может быть другой итерационный цикл или цикл с известным числом повторений. Другими словами, в итерационных циклах никаких ограничений на вложенные циклы не накладывается.
Примеры реализации итерационного цикла
Пример 1.15. Составить программу для вычисления функции, заданной рекурсивными формулами:
Y0=(1+X)/3
Yk +1 =Yk+ (X/Yk ·Yk - Yk)/3 при k=l, 2, 3.... Вычисления закончить при выполнении условия:
|Yk+l -Yk | < е,
где е — точность вычислений (малое положительное число). Аргумент функции Х—произвольное число.
Решение.
Анализ постановки задачи
Исходные данные для решения: аргумент функции — Х и точность вычисления — Е.
То, что заданы рекурсивные формулы для вычислений, означает повторяемость (цикличность) вычислений: каждое новое значение функции вычисляется по ее предыдущему значению. Число вычислений неизвестно, но известно условие продолжения вычислений: пока |Yk+1 - Yk | Е.
Введем обозначения объектов программы: Y0 — предыдущее (в том числе начальное) значение функции; Y —очередное (в том числе конечное) значение функции; Z — модуль разности значений.
Для решения задачи будем использовать цикл WHILE.
Как и любой другой, этот цикл требует подготовки. В первую очередь необходимо обеспечить истинность выражения ZE.
Значение Е определим на этапе ввода исходных данных, а значение Z определим до входа в цикл, присвоив ему любое значение, которое больше Е, например Z:=2*E.
Также до входа в цикл необходимо вычислить начальное значение функции Y0:=(1+X)/3.
Наконец, тело цикла. В нем вычисляется очередное значение функции
Y:=Y0+(X/Y0/Y0-Y0)/3.
Здесь же необходимо обеспечить изменение значения выражения в заголовке цикла Z:=ABS(Y-Y0).
Наконец, необходимо подготовить следующую итерацию Y0:=Y.
Выход из цикла произойдет при достижении заданной точности вычислений. После этого можно выводить полученные результаты.
С целью большей информативности результатов дополним алгоритм вычислением числа выполненных итераций К:=К+1
Начальное значение К присвоим до цикла К:=1
Результаты вычислений выведем в следующем виде:
Результаты вычислений
Аргумент: **.**
Заданная точность: *.*****
Значение функции: ****.***
Число итераций: ***
Поскольку алгоритм уже достаточно детализирован, составим текст программы:
Текст программы
PROGRAM Prim115;
{Вычисление функции с заданной точностью}
VAR
X, Y0, Y, E, Z : REAL;
K : INTEGER;
{Х – Аргумент функции}
{Y0, Y – Начальное и конечное значения функции}
{Е – Заданная точность}
{Z=ABS(Y-Y0)}
{K – число итераций}
BEGIN
{Этап ввода исходных данных}
WRITE(‘Аргумент функции’);
READLN(X);
WRITE(‘Заданная точность вычислений’);
READLN(E);
{Этап вычислений}
Z:=2*E;
Y0:=(1+X)/3;
K:=1;
WHILE Z>=E DO
BEGIN
Y:=Y0+(X/Y0/Y0-Y0)/3;
Z:=ABS(Y-Y0);
Y0:=Y;
K:=K+1
END;
{Этап вывода результатов}
WRITELN(‘Результаты вычислений');
WRITELN(‘Аргумент:’,X:5:2);
WRITELN(‘Заданная точность:',E:7:5);
WRITELN(‘Значение функции:’,Y:8:3);
WRITELN(‘Число итераций:’,K:3);
END.
Пример 1.16. Вычислить сумму при х =0,5.
Суммирование прекращать, когда очередной член суммы будет меньше заданного е = 0.0001.
Решение.
В приведенной ниже программе используется цикл REPEAT:
PROGRAM Prim116;
VAR
X, Eps, S, A : REAL;
N : INTEGER;
BEGIN
X := 0.5;
Eps:=0.0001;
S:=0;
N:=1;
REPEAT
A:=cos(n*x)/n;
S:=s+a;
N:=N+1;
UNTIL a<Eps;
WRITELN( ‘Сумма равна ‘,S:8:5);
End .
Пример 1.17. Определить приближенное значение суммы элементов ряда:
S = l + x/1! + x3/3! + x5/5! +...
Суммирование выполнять до тех пор, пока очередное слагаемое не станет меньше заданной величины Е.
Решение.
Анализ условия задачи
Исходными данными для решения задачи являются значения Х и Е, где Е — точность вычислений.
Вычисление суммы элементов ряда — цикл с неизвестным числом повторений.
Очевидно, что условие выполнения операторов тела цикла можно записать в виде
WHILE A>=E DO,
где А — очередной элемент ряда;
Е — заданная точность вычислений.
В теле цикла следует:
— накапливать в переменной S значение предыдущего элемента ряда;
-
получать новое значение элемента ряда.
Для вычисления нового элемента ряда необходимо определить закономерность изменения последующего элемента по сравнению с предыдущим.
Чтобы найти эту закономерность, попарно сравним соседние элементы и проанализируем выражение, на которое в каждом цикле нужно умножать предыдущий элемент. Результаты сравнения представлены в таблице.
Номер цикла |
Предыдущий элемент |
Выражение |
Новый (последующий) элемент |
1 2 3 |
Х/1 X 3/1·2·3 X 5/1·2·3·4·5 |
X 2/2·3 X 2/4·5 X 2/6·7 |
X 3/1·2·3 X 5/1·2·3·4·5 X 7/1·2·3·4·5·6·7 |
Из приведенной таблицы видно, что числитель выражения от цикла к циклу не меняется: X 2.
Знаменатель — произведение двух соседних натуральных чисел, то есть если первое число обозначим переменной К, то в общем виде выражение можно записать: P=X · Х/(K · (K + 1)), а значение К изменяется в каждом цикле на 2.
Итак,
WHILE A>=E DO
Begin
S:=S+A;
Р:=Х*X/(К*(К+1)) ;
А:=Р*А ;
К:=К+2 ;
END;
И последнее. До входа в цикл следует определить значения переменных S, А, К:
S:=1;
А:=Х;
К:=2;
(см. условие примера)
Возможный вариант программы
PROGRAM Prim117;
VAR
X, E, S, A, K, P: REAL;
{X – переменная для ввода и хранения аргумента
Е – переменная для ввода и хранения точности вычислений
S – переменная для получения суммы элементов ряда
A – переменная для получения очередного элемента ряда
К – переменная для получения знаменателя
P – переменная для вычисления значения выражения, на которое умножается предыдущий элемент}
{Блок ввода информации}
BEGIN
WRITE (‘Введите значение аргумента’);
READLN(Х);
WRITE (‘Введите точность вычислений’);
READLN(Е);
{Блок вычисления суммы}
S:=1;
А:=Х;
K:=2;
WHILE A>=E DO
BEGIN
S:=S+A;
P:=X*X/(К*(К+1)) ;
A:=А*Р ;
К:=К+2 ;
END ;
WRITELN(‘При значении аргумента = ’ , X);
WRITELN(‘Сумма элементов ряда = ’, S)
END.
Пример 1.18. Вычислить сумму
S =
для значений x, изменяющихся в пределах от 0.2 до 1 с шагом 0.2. Суммирование прекращать, когда очередной член суммы по абсолютной величине станет меньше е = 0.0001.
Решение.
Задача сводится к организации вложенных циклов. Внешний цикл по счетчику обеспечивает изменение х. Во внутреннем цикле по условию осуществляется вычисление суммы.
Член суммы an целесообразно представить в виде двух сомножителей: