Вы на НеОфициальном сайте факультета ЭиП

На нашем портале ежедневно выкладываются материалы способные помочь студентам. Курсовые, шпаргалки, ответы и еще куча всего что может понадобиться в учебе!
Главная Контакты Карта сайта
 
Где мы?

Реклама


Циклические алгоритмы

Просмотров: 2742 Автор: admin

Операторы цикла организуют повторение фрагментов алгоритма при сохранении общей линейной схемы.

Циклические алгоритмы можно условно разделить на две группы:

1.       Арифметический цикл, у которого заранее известно число повторений.

2.       Итерационный цикл, у которого заранее неизвестно число повторений.

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

Можно выделить четыре составные части цикла:

1.       Подготовка цикла (присваивание начальных значений переменным, в том числе параметру цикла).

2.       Тело цикла – это фрагмент, который должен быть повторен многократно.

3.       Изменение параметра цикла, как правило, выполняется в теле цикла.

4.       Проверка условия завершения цикла. В проверке условия явно или нет, присутствует параметр цикла.

Не всегда эти составляющие присутствуют явным образом.

В Си++ существуют три вида операторов цикла.


1. while…do:
while (условие)
           {         //Количество повторений любое.
                       тело цикла
           }
2. do…while:
do
           {         //Количество повторений любое.
                       тело цикла
           }
while (условие)
3. for:
for (объявление параметра цикла)
{                     //Количество повторений фиксировано.
                       тело цикла
}

С помощью каждого из этих операторов можно организовать циклический алгоритм любого типа.

Пример №1. Алгоритм построения таблиц значений различных функций. Это, чаще всего, арифметический цикл, потому что число повторений известно. Чаще всего, параметром цикла является аргумент функции. Пусть функция задана формулой вычисления значения y(x) = F(x). Известен диапазон изменения аргумента xÎ [x0, xn] и шаг изменения аргумента Dx.

Общая схема этого алгоритма на основе цикла while ... do выглядит так:

// Печать заголовка


x = x0;                                   // Подготовка цикла.
while (x <= xn)                        // Проверка условия завершения.
           {
                       y = F(x);         // Сколь угодно сложный алгоритм вычисления значения.
                       // Вывод строки таблицы.
                       x += Dx;         // Приращение управляющей переменной.
           };                               // Выход из цикла.
Общая схема этого алгоритма на основе цикла do ... while выглядит так:
// Печать заголовка
x = x0;                                   // Подготовка цикла.
do
           {
                       y = F(x);         //Сколь угодно сложный алгоритм вычисления значения.
                       // Вывод строки таблицы.
                       x += Dx;         // Приращение управляющей переменной.
           }
while (x <= xn);                     // Проверка условия завершения.
Общая схема этого алгоритма на основе цикла for выглядит так:
// Печать заголовка
for (x = x0; x <= xn; x += Dx) // Все составляющие цикла в заголовке.
           {
                       y = F(x);         // Сколь угодно сложный алгоритм вычисления значения.
                       // Вывод строки таблицы.
           };

Пример №2. Функция F(x) может быть достаточно сложной, и для вычисления значения в точке одной формулы недостаточно. В этом случае в теле цикла нужно позаботиться лишь о правильной записи блока, вычисляющего функцию. Например, для значений xΠ[–p/2; +p/2] нужно вычислить таблицу значений функции, имеющей разрыв в точках | x | = p/4:

 


// Код программы примера №2.
#include <stdio.h>
#include <math.h>
void main (void)
{
float    x, y;                            // Аргумент и значение функции.
// Вывод шапки таблицы в текстовом режиме экрана.
printf ("n Таблица значений функцииn");
printf ("--------------------------------n");
printf ("             x         y            n");
printf ("-------------------------------n");
// x – параметр цикла, в заголовке цикла задано полное управление.
for (x= – M_PI / 2.; x < = M_PI / 2.; x += 0.2 )  // Цикл вычисления таблицы.
           {
           if (fabs (x) <= M_PI / 4/)
                       y = sin (x);                           // Это блок вычисления значения функции.
           else                                                 // Логическая запись формулы вычисления.
                       y = cos (x);
printf ("%11.2f %11.2fn" ,x, y);              // Вывод строки таблицы.
}
}

Здесь константа M_PI – значение числа p, определена в библиотеке math.h.

Пример №3. Итерационный цикл используется в любой задаче, где условие завершения цикла нельзя оценить простым сравнением управляющей переменной с числом, например <= 5. В формулировке такой задачи явно или неявно присутствует условие «пока не будет выполнено» или «до тех пор, пока не выполнено», при произвольном содержании тела цикла. Для организации таких алгоритмов используются циклы whiledo или dowhile.

Пример использования цикла, управляемого событием, уже был ранее показан в примерах 3 и 4 предыдущего раздела. Еще одним случаем, когда цикл do  while необходим, является проверка корректности вводимых данных. При организации ввода нужно, чтобы программа была дружественна пользователю, то есть сначала следует показать, что и как вводить, а затем программно предусмотреть проверку значений введенных данных, чтобы в случае ошибки пользователь повторил ввод.

Пусть требуется найти площадь треугольника по значениям длин его сторон. Из трех заданных отрезков не всегда можно построить треугольник, а только тогда, когда длина каждой стороны меньше, чем сумма длин двух других сторон. При вводе данных пользователь может об этом забыть, тогда итоговое значение не будет найдено.


// Код программы примера №3.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main (void)
{
float    a, b, c;                         // Длины сторон треугольника.
float    S;                                // Площадь треугольника.
// Цикл проверки корректности введенных данных.
do
           {
           printf ("Введите длины сторон треугольникаn");
           scanf ("%f%f%f", &a, &b, &c);     // Тут может появиться ошибка данных.
           }
while (! (a < b + c && b < a + c && c < a + b));
// К вычислениям не перейдет, пока не получит корректных данных.
float    pp;
  pp = (a + b + c) / 2.;
S = sqrt (pp*(pp – a)*(pp – b)*(pp – c));
           printf ("Площадь треугольника равна: %6.2fn",S);
}

Пример №4. Управление итерационным циклом организует программист, который должен позаботиться и об инициализации управляющей переменной, и об ее приращении, и об условии завершения цикла.

Сформулируем условие задачи: мяч брошен вертикально вверх со скоростью V. Требуется построить таблицу зависимости высоты Y от времени t до момента падения мяча на землю. Формула вычисления , где g – константа тяготения, равная 9,8.

При движении мяч сначала взлетает вверх, затем начинает падение. Высота подъема и время полета мяча зависят от начальной скорости броска V.

Очевидно, что циклом вычисления должна управлять переменная t (время). Для нее известно начальное значение (t = 0). Шаг изменения можно оценить из физического смысла задачи и выбрать произвольно, например, t =0.1 сек. Момент завершения вычислений неизвестен в числовом выражении. Однако известно, что интересующее нас значение высоты сначала будет возрастать, затем убывать, и при падении мяча на землю примет значение, равное нулю: Y <= 0. Величина Y – прямая функция от  t, значит, в этом условии переменная t присутствует, но неявно.


// Код программы примера №4.
#include <stdio.h>
#include <conio.h>
#define                       G         9.8
void main (void)
{
float    V, y, t;                         // Имена переменных имеют физический смысл.
printf ("Введите значение скорости броскаn";
scanf ("%f", &V);
printf ("Таблица зависимости высоты от времени Y(t)n");
printf ("------------------------------------n");
printf ("          t                     y(t)     n");
printf ("------------------------------------n");
// Подготовка цикла. Момент времени  t= 0.1
t = 0.1;
do                                                    // Цикл do, так как при t= 0 высота Y(t) = 0.
{
           y = V * t – 0.5*G*t*t;
           printf ("t %6.2f t %6.2f n", t, y);
           t += 0.1;                               // Переход на новую итерацию.
} while (y >= 0);                              // В условии t присутствует неявно.
getch ();                                            // Для того, чтобы держать таблицу на экране.
}

Последнее значение таблицы будет отрицательным, потому что точного совпадения координаты y с нулем не будет никогда, а цикл do проверяет условие завершения после печати строки таблицы. Чтобы избежать этой некорректности, слудует выбрать цикл while, в котором отчетливо прописать условие завершения цикла: while (V * t – 0.5*G*t*t>=0).

В рассмотренных примерах циклические алгоритмы являются простыми. Сложным (вложенным) циклом называется такой, у которого содержанием циклически выполняемого фрагмента является также циклический алгоритм. Типы циклических алгоритмов при этом могут быть любыми. Внутренний цикл, от подготовки до завершения, должен находиться внутри внешнего, точнее, быть его телом.

Пример №5. Сложный арифметический цикл. Функция двух переменных F(x, y) или функция с параметром F(А, x) порождает необходимость использования сложного арифметического цикла в том случае, когда оба аргумента изменяются. Здесь решается задача полного перебора, то есть нахождения всех возможных значений функции при всех возможных значениях ее аргументов.

При решении таких задач необходимо выделить обе управляющие переменные, описать закон их изменения, и выбрать, какая из них по логике задачи главная. Главная или условно главная переменная будет параметром внешнего цикла, другая – параметром внутреннего цикла. Для каждого зафиксированного значения главной переменной другая переменная должна пробегать все значения своего диапазона. В сложном арифметическом цикле можно строить таблицу значений функции вида F(x, y) для всех возможных значений x и y. Чтобы значение параметра внешнего цикла не повторялось во многих строках таблицы, его следует выводить однократно во внешнем цикле как заголовок таблицы.

Пусть требуется вычислить объемы нескольких цилиндрических емкостей по формуле вычисления объема цилиндра , где H – высота, а d – диаметр основания цилиндра. Высота может изменяться в диапазоне H Î [–1;5] c шагом 1, а диаметр в диапазоне d Î [0.5; 3.5] c шагом 0.5. В качестве внешнего здесь можно выбрать любой цикл, так как переменные равноправны. Пусть это будет высота, тогда для одного зафиксированного значения высоты нужно выводить таблицу значений функции F (d).


// Код программы примера №5.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void)
{
float    d, h;                           // Диаметр основания и высота емкости.
float    V;                              // Объем емкости.
// Управление внешним циклом, параметр h.
for (h = 1.; h <= 5.; h += 1.)
{
           clrscr ();                     // Очистка экрана перед выводом очередной таблицы.
           printf ("Таблица зависимости объема от диаметра основанияn");
           printf("--------------------------n");
           printf ("  Высота = %6.2fn", h);
           printf ("          d         V n");
           printf ("--------------------------n");
           // Управление внутренним циклом, параметр d.
           for (d = 0.5; d <= 3.5; d += 0.5)
           {
                       V = M_PI * pow (0.5*d, 2.);
                       printf ("%6.2f t %6.2f n", d, V);
           }
getch();                      // Удержание экрана после вывода очередной таблицы.
}
}

Очистка экрана перед выводом очередной таблицы (функция clrscr ()) не необходима. В этом варианте на очередном экране мы будем видеть одну таблицу для одного значения высоты. Если закомментировать эту строку, то таблицы будут выводиться подряд одна за другой. Удержание экрана после вывода очередной таблицы необходимо, так как эта программа выводит данных больше, чем вмещается на один экран.

Пример №6. Сложный итерационный цикл. Для того чтобы показать, что сложность – понятие относительное, изменим текст примера №3 добавлением к нему цикла, управляемого событием, как в примере 3 предыдущего раздела. Никакого отношения по управлению к внутреннему циклу он иметь не будет, только содержать его в своем теле. Новый цикл охватит весь текст старой программы, и будет управлять ее многократным повторением.


// Код программы примера №6.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main (void)
{
float    a, b, c;                        // Длины сторон треугольника.
float    S;                                // Площадь.
// Цикл, управляющий процедурой многократных вычислений.
do
{
           // Цикл проверки корректности введенных данных.
           do
                       {
                                  printf ("Введите длины сторон треугольникаn");
                                  scanf ("%f%f%f", &a, &b, &c); // Тут может появиться ошибка.
                       }
           while (!(a < b + c && b < a + c && c < a + b));
float pp;
pp = (a + b + c) / 2.;
S = sqrt (pp*(pp – a)*(pp – b)*(pp – c));
           printf("Площадь треугольника равна: %6.2fn",S);
// Управление внешним циклом.
printf("Если больше нет треугольников, нажмите ESCn");
} while (getch () != 27);
}
Пример №7. В сложном цикле типы циклических алгоритмов могут быть произвольными, например, внешний цикл – итерационный, а внутренний арифметический, и наоборот. Изменим пример №4, использующий итерационный цикл, добавлением необходимости исследования решения задачи для различных значений стартовой скорости V. Пусть V может изменяться в диапазоне V Î [–1;7] c шагом 1. Очевидно, что в этом случае решение задачи должно быть повторено многократно, а именно, 7 раз. Переменная V из простой превращается в управляющую. Текст примера нужно изменить добавлением к нему управления по переменной V во внешнем цикле, при этом запись внутреннего цикла не изменяется ни в одном символе.
// Код программы примера №7.
#include <stdio.h>
#include <conio.h>
#define                      G         9.8
void main (void)
{
float    V, y, t;                         // Имена переменных имеют физический смысл.
           // Управление внешним циклом, параметр V.
           for (V = 1; V <=7 ; V += 1.)
           {
           clrscr ();
           printf ("Таблица зависимости высоты от времени при V=%6.2fn", V);
           printf ("-----------------------------n");
           printf ("          t           y(t)    n");
           printf ("-----------------------------n");
           // Управление внутренним циклом, параметр t.
           // Подготовка цикла. Момент времени t= 0.1
           t = 0.1;
           while (V * t – 0.5*G*t*t >= 0)
           {
                       y = V * t – 0.5*G*t*t;
                       printf ("t %6.2f t %6.2f n", t, y);
                       t += 0.1;                    // Переход на новую итерацию.
           }
           getch ();                                // Для того, чтобы держать таблицу на экране.
           }
}

Варианты заданий.

Задание 1. Составить программу для вычисления таблицы значений функции:

Значение а ввести. На интервале х Î [–4;6] иметь в цикле не менее 15-ти точек. Иметь возможность повторного обращения в диалоге.

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

где g=6,67*108, m2 = 4*108.

r Î [0,1; 0,9], шаг 0,2; m1 Î [3*108; 4*108], шаг 0.5*108.

Результаты свести в таблицу. Для каждого m1 строить отдельную табличку F(r), где m1 напечатано в заголовке.

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

если х Î [–4 ; 4], шаг 0,3. Параметр а принимает значения 1.2, 1.3, 1.4, 1.5, 1.6. Для каждого значения параметра строить отдельную табличку y(x).

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

если х Î [–6; +6] с шагом 0.5.

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

Значения радиусов r и R вводить.

Для y Î [0; 2.4] с шагом 0.8 и x Î [0; 2.4] с шагом 0.6 построить таблицу на решетке из полного перебора значений x, y, где y выводить в заголовке.

Задание 6. Составить программу для вычисления таблицы значений функции:

 

если x Î [–1; 5], шаг 1. Угол j принимает последовательно значения π/2, π/3, π/6, π/9.

Результаты свести в таблицу; для каждого j строить отдельную табличку T(x), где j напечатано в заголовке.

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

Задание 8. Составить программу, которая находит наибольший общий делитель двух натуральных чисел a и b по следующему алгоритму: до тех пор, пока a и b не сравняются, вычитать = a  b при > b, или b = b  a при > a. Исходные числа вводить, иметь возможность повторного обращения в диалоге.

Задание 9. Натуральное число является простым, если оно делится на 1 и на самого себя. Натуральное число является совершенным, если оно равно сумме своих делителей, включая 1, например

6 = 1 + 2 + 3,

28 = 1 + 2 + 4 + 7 + 14.

Составить программу, которая определит, является ли некоторое число N простым, а если нет, то является ли оно совершенным. Иметь возможность повторного обращения в диалоге.

Задание 10. Для любого действительного числа x вычислить значение f(x), где f – периодическая функция с периодом Т = 2 , совпадающая на отрезке [0, 1] c функцией y(x) = x2 – 2,25×x, а на отрезке [1, 2] с функцией y(x) = x – 1.25.

Проверить в цикле на интервале x Î [–4; 4] для четного числа точек.

Задание 11. Натуральное число является простым, если оно делится только на 1 и на самого себя. Составить программу, которая найдет все простые числа от N1 до N2 включительно. Иметь возможность повторного обращения в диалоге.

Задание 12. Составить программу для проверки навыков знания столбца таблицы умножения на N, где N = 2, 3, ... 10 (выбирать в диалоге).

Подсчитывать правильные ответы, выставить оценки: «отлично», «хорошо», «удовлетворительно» или «неудовлетворительно» за 10, 9, 8, 7 и менее соответственно. Иметь возможность повторного обращения в диалоге.

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

Задание 14. Для любого действительного x вычислить значение f(x), где f – периодическая функция с периодом T = 2.5 , совпадающая на отрезке [0, 1] c функцией y(x) = x2 , а на отрезке [1, 1.5] с функцией y(x) = – x.

Проверить на интервале x Î [–3;5] для не менее чем 10 точек.

Задание 15. Для любого натурального числа N найти все такие натуральные x, y, для которых выполняется  N = x2 + y2 . Иметь возможность повторного обращения в диалоге.

Задание 16. Найти все целочисленные координаты точек, попадающих в круг радиуса R с центром в точке (A, B). Иметь возможность повторного обращения в диалоге.

Задание 17. Составить программу, вычисляющую температуру воздуха на разных высотах:

 

Построить таблицу значений для h Î [0;45000], шаг 1000.

Задание 18. Составить программу для вычисления таблицы значений функции, где

если x Î [–2; 4], шаг 0.25.

Задание 19. Найти все натуральные числа от N1 до N2 , запись которых есть палиндром. Иметь возможность повторного обращения в диалоге.

Задание 20. Найти все натуральные числа от N1 до N2, запись которых совпадает с последними цифрами записи их квадрата, например: 62 = 36, 252 = 625 и т.д. Иметь возможность повторного обращения в диалоге.


Информация

Комментировать статьи на нашем сайте возможно только в течении 60 дней со дня публикации.

Популярные новости

Статистика сайта



Rambler's Top100



 
Copyright © НеОфициальный сайт факультета ЭиП