Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Posobie_Programmirovanie_1_Kurs_1_Sem_Anosov_Yu...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.2 Mб
Скачать

Var x1, x2, Xn : real; // Вычисляемые числа

S : real; // Вычисляемая сумма чисел

R : real; // Граница вычислений, вводимая пользователем

Этап второй. Разработка программы, реализующей вычисления при помощи простой не рекурсивной функции.

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

Посмотрим ещё раз на нашу задачу.

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

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

Начальные значения переменных «X1», «X2» и переменной содержащей начальную сумму, должны быть заданы до начала цикла. А в процессе выполнения цикла – значения данных переменных должны будут изменяться в соответствии с формулой, заданной в условии задачи.

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

Var x1, x2, Xn : real; // Вычисляемые числа

S : real; // Вычисляемая сумма чисел

R : real; // Граница вычислений, вводимая пользователем

Begin

// Ввод границы вычислений и установка начальных значений

Write(‘введите границу вычислений. R=’);

Readln(R);

X1:=0;

X2:=1;

S :=1;

Writeln(X1);

Writeln('X = ', X2, ' Сумма = ', S);

// Основной цикл

While (S<=R) do

begin Xn:=(X1+X2)/2;

S:=S+Xn;

Writeln('X = ', X2, ' Сумма = ', S);

X1:=X2;

X2:=Xn;

End;

End.

Казалось бы, базовый алгоритм готов.

Однако, посмотрим на результаты работы данной программы:

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

Действительно, для введённой границы R=3, вычисления должны были закончится на шаге: X = 0.625 Сумма = 2.875

Наша же программа выполнила ещё один шаг и выдала:

X = 0.6875 Сумма = 3.5625

Вопрос.

Каким образом следует изменить разработанный нами базовый алгоритм, чтоб он не выполнял лишнего действия?

Самый простой способ – это заменить цикл с предусловием на цикл с постусловием. Переместив в него вычисление и печать первой суммы и изменив условие прекращения работы цикла.

Var x1, x2, Xn : real; // Вычисляемые числа

S : real; // Вычисляемая сумма чисел

R : real; // Граница вычислений, вводимая пользователем

Begin

// Ввод границы вычислений и установка начальных значений

Write('Введите границу вычислений. R=');

Readln(R);

X1:=0;

X2:=1;

Writeln('X = ', X1);

S :=X1;

Xn:=X2;

// Основной цикл

repeat

S:=S+Xn;

Writeln('X = ', Xn, ' Сумма = ', S);

Xn:=(X1+X2)/2;

X1:=X2;

X2:=Xn;

until ((S+Xn) > R);

End.

Теперь алгоритм будет работать верно:

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

Для начала осуществим преобразование алгоритма к варианту использования простой функции.

Пусть наша функция осуществляет вычисление и печать нового текущего значения «Xn» и полученной суммы «S».

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

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

Таким образом, функция будет иметь 4 параметра: начальные значения «X1» и «X2», граница вычислений «R», и параметр N – число итераций цикла.

В конце программы выведем ещё раз значение найденной суммы, число слагаемых и число итераций цикла.

Для повышения качества выводимых данных – немного изменим оператор вывода в цикле.

В результате программа примет такой вид: