Вложенные циклы

Пример 2.13. Вычислить при x, изменяющемся в пределах от 0,1 до 1 с шагом 0,05.

Вначале ограничимся вычислением суммы при заданном значении х. Здесь член суммы необходимо вычислять рекуррентно. Для вывода рекуррентной формулы выпишем выражения для двух последовательных членов суммы, например (i – 1)-го и i-го, и, разделив i-ый член на (i–1)-й, получим выражение, на которое необходимо домножить (i-1)-й член для получения i-го. Итак,

Таким образом, чтобы получить i-й член из предыдущего (i-1)-го члена, его нужно домножить на 2х/i.

Вычисление суммы для фиксированного значения х может быть осуществлено следующим образом:

double s, a, x = 0.1;

s = 1; a = 1;

for (int i = 1; i <= 12; i++)

{

a = a * 2 * x / i;

s = s + a;

}

Console.WriteLine("{0:f4} {1:f4}", x, s);

Эта последовательность операторов должна быть выполнена в цикле по x:

double s, a, x;

double xh = 0.1, xk = 1.0001, h = 0.05;

int n = (int)((xk - xh) / h + 1);

x = xh;

for (int j = 1; j <= n; j++)

{

s = 1; a = 1;

for (int i = 1; i <= 12; i++)

{

a = a * 2 * x / i;

s = s + a;

}

Console.WriteLine("{0:f4} {1:f4}", x, s);

x = x + h;

}

Console.ReadKey();

Такая структура программы, когда цикл выполняется внутри другого цикла, называется вложенными циклами. Далее приводится результат выполнения программы.

Замечание. В операторе вывода строка формата содержит пробелы, что обеспечивает разделение при выводе столбцов значений x и s.

Пример 2.14. Вычислить сумму

для значений х, изменяющихся в пределах от 0,2 до 1 с шагом 0,2. Суммирование прекращать, когда очередной член суммы по абсолютной величине станет меньше e = 0,0001.

Задача сводится к организации вложенных циклов. Внешний цикл по счетчику обеспечивает изменение х (см. пример 2.13). Во внутреннем цикле по условию осуществляется вычисление суммы (см. пример 2.9).

Член суммы ai имеет более сложный вид, чем в примере 2.9. Его целесообразно представить в виде двух сомножителей:

ai = ci(2i – 1),

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

Число значений х на отрезке от 0,2 до 1 с шагом 0,2 равно 5. В программе для контроля при каждом значении х вычисляется также функция , которая приближенно может быть представлена в виде указанной суммы:

const double xh = 0.2, h = 0.2, eps = 0.0001;

double a, x, s, y, c;

int n = 5, i;

x = xh;

for (int j = 1; j <= n; j++)

{

s = 1; c = -1; i = 1;

do

{

c = -c * x * x / ((2 * i - 1) * 2 * i);

a = c * (2 * i - 1);

s = s + a;

i = i + 1;

} while (Math.Abs(a) >= eps);

y = Math.Cos(x) + x * Math.Sin(x);

Console.WriteLine("x= {0:f4} s= {1:f4} y= {2:f4}",

x, s, y);

x = x + h;

}

Console.ReadKey();

Вопросы для самопроверки

1. Что такое цикл? Операторы цикла for, while, do … while. Различия между ними.

2. Какие данные необходимы для организации цикла for? Что такое управляющая переменная цикла?

3. Циклы по условию и их организация.

4. Операторы break и continue. В каких случаях они используются?

5. Типовые алгоритмы циклической структуры: вычисление суммы n слагаемых, вычисление произведения n сомножителей, вычисление факториала, табулирование функции.

6. Вычисление суммы с использованием рекуррентных соотношений.

7. Вложенные циклы.

8. Согласование (приведение) типов.

9. Вывод с использованием формата.

Задание для самостоятельного выполнения

1. Вычислить s = 2 + 5 + 8 + ... + 35.

2. Вычислить s = 2/3 + 4/5 + 6/7 + ... + 112/113.

3. Вычислить s = cos x + (cos 2x)/x + (cos 3x)/x2+ ... + (cos 9x)/x8.

4. Вычислить сумму s = cos x + (cos 2x)/22 + ... + (cos nx)/n2. Суммирование прекратить, когда очередной член суммы будет меньше ε = 0,0001.

5. Вычислить сумму квадратов 10 членов арифметической прогрессии

s = p2 + (p + h)2 + ... + (p + 9h)2.

6. Определить количество членов арифметической прогрессии

s = a + (a + h) + ... + (a + nh),

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

7. Получить таблицу функции y(x) = 0,5x2– 7x при изменении x от –4 до 4 с шагом 0,5.

8. Вычислить значение факториала числа 6 (6! = 1×2×3×...×6).

9. Вычислить s = 1! + 2! + ... + 6!

10. Вычислить s = (–1) 1·51/1! + (–1)2·52/2! + ... + (–1) 6·56/6!

11. Определить значение n, для которого р = 1 · 4 · 7...n не превышает L = 30 000.

12. Возвести число 3 в 7-ю степень, не используя операцию возведения в степень.

13. Вычислить при заданном x сумму s = 1 + 1/x + 1/x2 + ... + 1/x10.

14. Вычислить s = 1 + x2 + x4 + ... + x2n (x < 1). Вычисления прекратить, когда очередной член суммы будет меньше ε = 0,0001.

15. Начав тренировки, спортсмен в первый день пробежал 10 км. Каждый следующий день он увеличивал дневную норму на 7 % от нормы предыдущего дня. Определить:

а) какой суммарный путь пробежит спортсмен за 7 дней;

б) через сколько дней спортсмен пробежит суммарный путь 100 км;

в) через сколько дней спортсмен будет пробегать в день больше 20 км?

16. Вкладчик положил в банк 10 000 рублей под 8 % в месяц. Определить, через какое время сумма удвоится.

Следующие задачи требуют организации вложенных циклов. Вычислить сумму s, прекращая суммирование, когда очередной член суммы по абсолютной величине станет меньше 0,0001, при изменении аргумента x в указанном диапазоне [a, b] c шагом h. Для сравнения в каждой точке вычислить также функцию y = f(x), являющуюся аналитическим выражением ряда.

17.

18.

19.

20.

21.

22.

23.

24.

25.

Указание. В задании 17 при вычислении суммы для выхода из цикла нужно сравнивать с точностью 0,0001 не весь член суммы, а только xi, так как второй сомножитель при i = 4, 8 , … равен 0, что приведет к прекращению суммирования при i = 4 и таким образом исказит результат.

2.2. Организация разветвлений.
Разветвления в цикле

Разветвление – это структура, содержащая две ветви, из которых, в зависимости от условия, будет выполнена только одна. Разветвления организуются с помощью условного оператора if (см. п. 1.7.1):

if (выражение)

{

Операторы1;

}

[Else

{

Операторы2;

}]

. . .

Если выражение имеет значение true, то выполняются Операторы1, и происходит переход к оператору, следующему за if. Если выражение имеет значение false, то выполняются Операторы2, расположенные после else, и далее выполняется оператор, следующий за условным. Если вторая ветвь отсутствует (такая структура называется «обход»), то в случае невыполнения условия никаких действий не производится и сразу выполняется оператор, следующий за условным. Если блок (операторы, заключенные в {}) состоит из одного оператора и не содержит описаний переменных, то скобки можно не использовать.

Далее приводятся примеры программ с использованием разветвлений, разветвлений в цикле и множественного выбора (см. п. 1.7.5).

Пример 2.15. Составить программу для решения квадратного уравнения ax2 + bx + c = 0. Квадратное уравнение имеет решение, если дискриминант d = b24ac не является отрицательным, т.е. после ввода коэффициентов a, b и c нужно вычислить d и проверить условие d < 0. Если это условие выполняется, то нужно вывести сообщение «Уравнение не

имеет решения». Если условие не выполняется (d ³ 0), нужно вычислить и напечатать корни (возможность совпадения корней игнорируется).

double a, b, c, d, x1, x2;

Console.WriteLine("Введите a");

a = double.Parse(Console.ReadLine());

Console.WriteLine("Введите b");

b = double.Parse(Console.ReadLine());

Console.WriteLine("Введите c");

c = double.Parse(Console.ReadLine());

d = b * b - 4 * a * c;

if (d < 0)

Console.WriteLine("Уравнение не имеет решения");

else

{

x1 = (-b + Math.Sqrt(d)) / (2 * a);

x2 = (-b - Math.Sqrt(d)) / (2 * a);

Console.WriteLine("{0:f4} {1:f4}", x1, x2);

}

Console.ReadKey();

Пример 2.16. Вывести большее из двух чисел:

double x, y, u;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

u = x;

if (y > u)

u = y;

Console.WriteLine(u);

Console.ReadKey();

Пример 2.17. Найти максимальное из трех чисел:

double x, y, z, u;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

Console.WriteLine("Введите z");

z = double.Parse(Console.ReadLine());

u = x;

if (y > u)

u = y;

if (z > u)

u = z;

Console.WriteLine(u);

Console.ReadKey();

Пример 2.18. Определить, лежит ли точка с координатами x, y внутри или вне круга радиусом r с центром вначале координат:

string inside = "точка внутри круга";

string outside = "точка вне круга";

double x, y, r;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

Console.WriteLine("Введите r");

r = double.Parse(Console.ReadLine());

if (x * x + y * y <= r * r)

Console.WriteLine(inside);

else

Console.WriteLine(outside);

Console.ReadKey();

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

Второй вариант программы для решения этой задачи составлен с использованием логической переменной, в которую помещается результат (true, если точка внутри круга, false – в противоположном случае):

double x, y, r;

bool l = false;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

Console.WriteLine("Введите r");

r = double.Parse(Console.ReadLine());

if (x * x + y * y <= r * r) l = !l;

Console.WriteLine(l);

Console.ReadKey();

В операторе if логической переменной l присваивается значение true : выполняется операция отрицания (оператор !), если условие выполняется, т.е. точка лежит внутри круга. Подробнее о логических операциях см. гл. 1, п. 1.5.

Пример 2.19. Определить, лежит ли точка с координатами x, y внутри или вне квадрата, вершинами которого являются точки с координатами (1, 1), (–1, 1), (1, –1), (–1, –1).

Точка лежит внутри квадрата, если одновременно выполняются условия |x| < 1 и |y| < 1. Результат будем получать в логической переменной (см. пример 2.18):

double x, y;

bool l = false;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

if (Math.Abs(x) <= 1 && Math.Abs(y) <= 1) l = !l;

Console.WriteLine(l);

Console.ReadKey();

В операторе if логической переменной l присваивается значение true: выполняется логическая операция «И» (оператор &&), если условие выполняется, т.е. точка лежит внутри квадрата. Подробнее см. гл. 1, п. 1.5.

Пример 2.20. Определить, лежит ли точка с координатами x, y внутри или вне треугольника с вершинами в точках (0, –1), (0, 1), (1, 0).

Точка принадлежит треугольнику, если одновременно выполняются два условия x ³ 0 и x+|y| £ 1.

double x, y;

bool l = false;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

if (x >= 0 && Math.Abs(y) + x <= 1) l = !l;

Console.WriteLine(l);

Пример 2.21. Вводя координаты n точек x, y, определить, сколько из них попадет в круг радиусом r с центром в начале координат:

double x, y, r;

int i, n, k;

Console.WriteLine("Введите количество точек");

n = int.Parse(Console.ReadLine());

Console.WriteLine("Введите радиус");

r = double.Parse(Console.ReadLine());

k = 0;

for (i = 1; i <= n; i++)//вместо i = i + 1

{

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

if (x * x + y * y <= r * r) k++;

}

Console.WriteLine(

"В круг попало {0} точек из {1} ", k, n);

Console.ReadKey();

Пример 2.22. Ввести координаты точки x, y. Вычислить по выбору радиус-вектор точки, площадь прямоугольника с вершинами в точках (0, 0), (x, 0), (0, y), (x, y) или длину окружности, проходящей через точку x, y, с центром в начале координат.

Для выбора варианта вычислений используем оператор switch. Вариант вычислений будем задавать цифрой 1, 2 или 3:

double x, y, r;

int k = 0;

Console.WriteLine("Введите x");

x = double.Parse(Console.ReadLine());

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

Console.WriteLine(

"Признак: 1 = радиус - вектор,"

+ " 2 = площадь прямоугольника, "

+ " 3 - длина окружности");

Console.Write("Введите признак 1, 2 или 3: ");

k = int.Parse(Console.ReadLine());

switch (k)

{

case 1:

r = Math.Sqrt(x * x + y * y);

Console.WriteLine("радиус вектор {0:f}", r);

Console.ReadLine();

break;

case 2:

r = x * y;

Console.WriteLine(

"площадьпрямоугольника {0:f}", r);

Console.ReadKey();

break;

case 3:

r = 2 * Math.PI * Math.Sqrt(x * x + y * y);

Console.WriteLine(

"длина окружности {0:f}", r);

Console.ReadKey();

break;

default:

Console.WriteLine(

"Неверный выбор. Выберите 1, 2 или 3.");

Console.ReadKey();

break;

}

Вопросы для самопроверки

1. Что такое разветвление? Какой оператор используется для организации разветвлений?

2. Обход и его реализация на языке C#.

3. Множественный выбор и его реализация на языке C#.

4. Логические переменные, логические операторы, логические выражения и их использование в программах.

Задание для самостоятельного выполнения

1. На плоскости расположена окружность радиусом r с центром в начале координат. Ввести заданные координаты точки и определить, лежит ли она на окружности. Решить задачу при r=2 для точек с координатами (0, 2), (1,5, 0,7), (1, 1), (3, 0).

Указание. Считать, что точка с координатами х, у лежит на окружности радиусом r, если |х2+у2r2|£10–3.

Определить, лежит ли заданная точка внутри или вне треугольника с вершинами в точках (–1, 0), (1, 0), (0, 1).

Указание. Уравнение прямой, ограничивающей фигуру слева: у = 1+х (х<0), справа: у = 1 – х (х ³ 0). Следовательно, точка принадлежит фигуре, если у ³ 0 и у + |х| £ 1.

3. Для заданных a и b получить с = max(a, b), если а > 0 или с = min(a, b), если а £ 0.

4. Для заданных a, b, c вычислить z = max(min(a, b), c).

5. Заданы площади: круга – r и квадрата – s. Определить, поместится ли квадрат в круге. Задачу решить при: 1) r = 70; s = 36,74; 2) r = 0,86; s = 0,74.

6. Для задачи 5 определить, поместится ли круг в квадрате. Задачу решить при: 1) r = 3,2; s=3,5; 2) r =3,2; s = 4; 3) r = 6; s = 9.

7. Вычислить значение функции y при заданном значении аргумента x по формуле y = 1, если >1, или y =, если .

8. Вычислить значение функции y при заданном значении аргумента x по формуле у = 0, если ½х½³1, или у = x2 – 1, если ½х½<1.

9. Вычислить значение функции y при заданном значении аргумента x по формуле у = 0, если х £ –1, или у = 1 + х, если –1 < x £ 0, или y = 1, если х>0.

10. Вычислить значение функции y при заданном значении аргумента x по формуле y = 1, если х £ –1, или у = –x, если 1 < x £ 1, или y = –1, если х>1.

Следующие задачи требуют сочетания циклов и разветвлений, а также использования множественного выбора. Предполагается, что количество вводимых исходных данных n задано (см. пример 3.2.7).

11. Определить средний рост девочек и мальчиков одного класса. В классе учится n учеников.

12. В компьютер вводятся по очереди координаты n точек. Определить, сколько из них попадет в круг радиусом r с центром в точке (a, b).

13. Ученику 1-го класса назначается дополнительно стакан молока (200 мл), если его вес составляет меньше 30 кг. Определить, сколько литров молока потребуется ежедневно для одного класса, состоящего из n учеников. После взвешивания вес каждого ученика вводится в компьютер.

14. В компьютер вводятся по очереди координаты n точек. Определить, сколько из них попадет в кольцо с внутренним радиусом r1 и внешним r2.

15. В соревнованиях по бегу принимают участие 30 спортсменов. Вводя по очереди результаты участников, определить, сколько из них выполнили заданный норматив.

16. В компьютер по очереди вводятся координаты n точек. Определить, сколько из них принадлежит фигуре, ограниченной осью абсцисс и аркой синусоиды, построенной для аргумента от 0 до p.

17. В компьютер вводятся координаты n точек, лежащих на плоскости. После ввода координат каждой точки выводить номер квадранта, в котором она находится. Определить количество точек, лежащих по отдельности в 1-м и 3-м квадрантах.

18. В компьютер вводятся координаты n точек, лежащих на плоскости. Напечатать номер точки, ближайшей к началу координат, и величину расстояния от нее до начала координат.

19. Вводя n значений r, вычислить по выбору площадь квадрата со стороной r, площадь круга радиусом r или площадь равностороннего треугольника со стороной r. Использовать множественный выбор.

20. Для n пар значений А, В вычислить по выбору площадь прямоугольника со сторонами А, В; площадь кольца, заключенного между двумя окружностями с радиусами А и В; площадь равнобедренного треугольника со сторонами А, B, В. Использовать множественный выбор.

2.3. Составление программ для обработки
потока данных

Часто требуется обрабатывать одинаковым образом данные, поступающие последовательно друг за другом. Возможны два случая:

· количество данных известно до начала выполнения программы. Тогда это значение используется в качестве верхней границы счетчика цикла (см. пример 2.21);

· количество данных заранее неизвестно. В этом случае для окончания ввода используется специальное значение того же типа, что и вводимые данные (признак конца ввода), которое заведомо не может встретиться в потоке данных.

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

Следующие примеры иллюстрируют эти приемы.

Пример 2.23.Определить средний рост учеников класса (в классе n учеников). В циклебудем вводить в переменную r рост очередного ученика и прибавлять его к сумме s. После выхода из цикла разделим суммарный рост на количество учеников (программа составлена для n = 5).

double sr, r, s = 0;

for (int i = 0; i < 5; i++)

{

Console.WriteLine("Введите рост ученика");

r = double.Parse(Console.ReadLine());

s = s + r;

}

sr = s / 5;

Console.WriteLine(sr);

Console.ReadKey();

Пример 2.24. Определить средний рост 14-летних подростков, проходящих диспансеризацию (количество заранее неизвестно).

Чтобы определить средний рост, будем в цикле вводить в переменную r рост очередного подростка и прибавлять его к сумме s, а количество подростков n увеличивать на 1. После выхода из цикла разделим суммарный рост на количество подростков.

Используем цикл do…while, для выхода из цикла будем использовать специальное значение, вводимое в r (например, 0):

double sr, r, s = 0;

int n = 0;

do

{

Console.WriteLine(

"Введите рост ученика, для окончания 0");

r = double.Parse(Console.ReadLine());

if (r == 0) break;

s = s + r;

n = n + 1;

} while (r > 0);

sr = s / n;

Console.WriteLine(sr);

Console.ReadKey();

Пример 2.25. Определить средний рост и вес 14-летних подростков, проходящих диспансеризацию.

Для организации цикла будем использовать специальное значение, вводимое в переменную r (рост), и вводить ее отдельно:

double sr, swr, r, w, s = 0, sw = 0;

int n = 0;

do

{

Console.WriteLine(

"Введите рост ученика, для окончания 0");

r = double.Parse(Console.ReadLine());

if (r == 0) break;

Console.WriteLine("Введите вес ученика");

w = double.Parse(Console.ReadLine());

s = s + r;

sw = sw + w;

n = n + 1;

} while (r > 0);

sr = s / n; swr = sw / n;

Console.WriteLine(

"Средний рост {0:f2} Средний вес {1:f2}",

sr, swr);

Console.ReadKey();

Пример 2.26. Вводя координаты x, y произвольного числа точек, определить в процентах долю точек, попавших в круг радиусом r с центром в начале координат.

Для окончания ввода будем использовать специальное значение. Пусть для всех вводимых точек x < 1000. Тогда значение x = 1000 будем использовать для окончания ввода.

double x, y, r;

int n = 0, k = 0;

Console.WriteLine("Введите радиус");

r = double.Parse(Console.ReadLine());

do

{

Console.WriteLine(

"Введите x, для окончания 1000");

x = double.Parse(Console.ReadLine());

if (x >= 1000) break;

Console.WriteLine("Введите y");

y = double.Parse(Console.ReadLine());

n = n + 1;

if (x * x + y * y <= r * r) k = k + 1;

} while (x < 1000);

if (n != 0) k = k * 100 / n;

Console.WriteLine(

"В круг попало k = {0:d}% точек", k);

Console.ReadKey();

Вопросы для самопроверки

Организация обработки потока данных, количество которых заранее не известно. Использование специального значения.

Особенности организации ввода, если каждая порция данных включает несколько значений.

Задание для самостоятельного выполнения

Решить задачи п. 3.2 для случая, когда количество данных заранее (до начала выполнения программы) неизвестно. В программе необходимо обеспечить прекращение ввода, как только входной поток иссякнет.