Циклы по условию необходимо организовывать, когда количество повторений цикла неизвестно и в ряде случаев является искомой величиной при решении задачи. Средства языка C# для организации циклов по условию приведены в п. 1.1.4.
Пример 2.8. Определить количество (n) членов арифметической прогрессии
,
сумма которых впервые превысит заданное число р.
На каждом шаге алгоритма нужно добавлять к сумме s очередной член m = a + i´h (s = s + m), i = 1, 2, ..., но при этом перед каждым прибавлением очередного члена проверять условие s £ p. Как только в первый раз условие не будет выполнено, т.е. s > p, необходимо выйти из цикла.
Далее приводится программа для решения задачи при a = 2, h = 3, p = 41. В программе текущее значение номера члена суммы обозначено через n. Значение этой переменной, при котором впервые оказалась s > p, и будет результатом:
int s = 0, n = 0, m;
const int a = 2, h = 3, p = 41;
while (s <= p)
{
m = a + n * h;
s = s + m;
n = n + 1;
}
//вычитается 1, прибавленная после
//последнего изменения суммы.
n = n - 1;
Console.WriteLine("{0:d}", n);
Console.ReadKey();
Второй вариант программы использует оператор цикла с проверкой условия после первого прохождения цикла:
int s = 0, n = 0, m;
const int a = 2, h = 3, p = 41;
do
{
m = a + n*h;
s = s + m;
n = n + 1;
} while (s <= p);
n = n - 1;
Console.WriteLine("{0:d}", n);
Console.ReadKey();
Замечание. Член суммы m можно было бы вычислять рекуррентно: m = m + h, задав до начала цикла m = a (в программу при этом нужно внести и некоторые другие изменения, которые рекомендуется выполнить самостоятельно).
Пример 2.9. Вычислить при x = 0,5. Суммирование прекратить, когда очередной член суммы будет меньше заданного ε = 0,0001.
double x = 0.5;
const double eps = 0.0001;
double s = 0, a;
int n = 1;
do
{
a = Math.Cos(n*x) / n;
s = s + a;
n = n + 1;
} while (Math.Abs(a) > eps);
Console.WriteLine("Сумма равна {0:f4}", s);
Console.ReadKey();
Пример 2.10. Методом итераций найти корень уравнения на отрезке [–1, 0,3] с точностью ε = 0,0001, принимая за начальное приближение x0 = –0,4 и вычисляя последовательно , i = 1, 2, 3, …, пока не будет выполнено условие .
При программной реализации метода итераций нет необходимости в использовании переменных с индексами. Для организации вычислительного процесса необходимо одновременно иметь в памяти значения лишь двух последовательных приближений (обозначим их х0 и х1). Следующее приближение х1 получается из предыдущего х0. Если условие достижения точности аbs(х1–х0)£ eps не выполняется, то следует переслать значение х1 в переменную х0 (х0 = х1) и получить в х1 следующее приближение.
При организации цикла проверку условия удобно осуществлять после первого прохождения цикла, т.е. использовать цикл do … while:
double x0 = -0.4;
const double eps = 0.0001;
double x1, d;
do
{
x1 = 0.5 * (Math.Sin(x0 * x0) - 1);
d = Math.Abs(x1 - x0);
x0 = x1;
} while (d >= eps);
Console.WriteLine("Корень равен {0:f4}", x1);
Console.ReadKey();
Пример 2.11. Вычислить частное p и остаток q от деления двух натуральных чисел r и t, не используя операцию деления. Число r можно представить в виде . Будем последовательно вычитать t из r и подсчитывать количество вычитаний в переменной p. Значение q – результат последнего вычитания, когда в первый раз будет выполнено условие .
int r, t, q, p = 0;
r = 26;
t = 8;
q = r;
while (q >= t)
{
q = q - t;
p = p + 1;
}
Console.WriteLine("Частное {0:d} Остаток {1:d}", p, q);
Console.ReadKey();
Здесь используется цикл с проверкой условия до первого выполнения тела цикла (что важно), так как возможен случай, когда r < t, и тело цикла не должно выполняться ни разу.
Пример 2.12. Корабль должен преодолеть путь в 3000 км. В первый день он прошел 200 км. Каждый следующий день он будет проделывать путь на 5 % больше, чем в предыдущий день. Через какое время он прибудет в порт назначения?
Обозначим путь одного дня через р. Вначале р = 200. Путь следующего дня вычисляется как р = р + 0.05р = 1.05р. Это значение прибавляем к суммарному пути s: s = s + р. Количество дней обозначим через n и будем увеличивать его каждый раз на 1:
double s = 0.0, p = 200.0;
int n = 0;
while (s < 3000)
{
s = s + p;
n = n + 1;
p = p * 1.05;
}
Console.WriteLine("{0:d}", n);
Console.ReadKey();