§ 8.8. Программирование циклических алгоритмов. Цикл с условием

Школьный курс C++
Содержание

Алгоритмическая конструкция цикл с условием

Цикл – это алгоритмическая структура, в которой одни и те же инструкции выполняются периодически, в зависимости от условия. В качестве условия (как и в условной инструкции) может быть любое выражение возвращающее числовое значение. Если оно отлично от нуля, то это интерпретируется как True. Если выражение вычисляется как 0 (в том числе, как действительный ноль 0.0), то это интерпретируется как False. Условие, которое вычисляется как True, позволяет выполнить один шаг цикла, который состоит в том, что будут выполнены одна или несколько инструкций, находящихся в теле цикла.

Существуют несколько разновидностей циклов. Все они сводятся к трем основным видам:

  • цикл с предусловием,
  • цикл с постусловием и
  • цикл с параметром.
Нужно сказать, что любой из этих типов цикла может быть заменен любым другим, а применяется тот или иной тип в зависимости от решаемой задачи и предпочтений разработчика. В python реализованы только две разновидности циклов: цикл с предусловием (изображен в виде блок-схемы на рисунке сверху) и цикл с параметром (также называемый циклом по переменной). Цикл с предусловием иначе называется циклом “типа while“. Название цикла говорит о том, что вначале будет проверяться условие цикла, а затем будет выполняться шаг цикла. Шаги цикла будут выполняться до тех пор, пока условие истинно. Из этого следует, что цикл может вообще не выполниться ни разу, если условие изначально ложно.

Инструкция while

В языке python цикл с предусловием реализован с помощью инструкции while. Инструкция while имеет следующий синтаксис:

while логическое_выражение:
    инструкции_1
[else:
    инструкции_2]

while в python отличается наличием необязательного блока else, который выполняется, если логическое выражение приобретает ложное значение.

Обратите внимание, что блок else будет выполнятся даже в том случае, если условие ложно изначально. Блок else не будет выполняться, если цикл прерывается инструкцией break или continue (см. в следующем уроке).

Этот тип цикла является универсальным, т. к. с помощью него может быть решена любая задача с циклом. Но цикл должен завершать свою работу по выполнению определенного количества шагов, а для этого необходимо изменять значения объектов (переменных влияющих на условие) в теле цикла так, чтобы условие могло, рано или поздно, принять значение False. В этом и есть основная сложность разработки циклического алгоритма с помощью while. Если алгоритм как следует не продумать, то цикл может уйти в бесконечное выполнение (“зацикливание”) и алгоритм никогда не завершит свою работу. Тем не менее, бесконечный цикл может быть организован намеренно (в программировании такое не редкость), скажем, для анализа вводимых данных.
Задача 1. Составить программу, в которой новое значение переменной присваивается в цикле.

Программа 8.8.1
a = True
while a:
    a = int(input('a = '))
else:
    print('Цикл завершил свою работу!')

В этом случае, выход из цикла программируется в теле цикла, например, с помощью инструкций if и break. В программе 8.8.1 цикл будет изменять значение переменной до тех пор, пока не будет введен 0.
Рассмотрим несколько типичных задач в которых используется цикл типа while.

Счетчики и накопители

Самым простым способом выхода из цикла – это проверка выполненных шагов цикла. Для этих целей используется переменная-счетчик. Эта переменная изменяет свое значение с шагом 1, начиная с 0. Нулевое значение переменной присваивается до входа в цикл, а в теле цикла переменной инкрементируется новое значение. В условии цикла сравнивается текущее значение счетчика с максимально возможным (количеством шагов).
Задача 2. Вывести на экран n-первых натуральных чисел.

Программа 8.8.2
n = int(input('n = '))
i = 0
while i < n:
    i = i + 1
    print(i, end=' ')

Вывод

n = 10
1 2 3 4 5 6 7 8 9 10

Блок-схема

Во многих задачах требуется “накапливать” значение переменной. Накапливать можно как сумму, так и произведение. Накопителю суммы до входа в цикл присваивается значение 0, а накопителю произведения – 1, т. е. значения, которые не изменят окончательный результат.
Примером задачи получения в цикле произведения является вычисление факториала числа: n! = 1 · 2 · 3 · ... · n.
Задача 3. Дано целое n. Получить значение n!

Программа 8.8.3
n = int(input('n = '))
i, p = 0, 1
while i < n:
    i = i + 1
    p = p * i
else:
    print(f'{n}! = {p}')

Вывод

n = 20
20! = 2432902008176640000
Факториал числа можно получить с помощью математического модуля math.factorial()

Аналогично программируется и накопление суммы.
Задача 4. С клавиатуры вводится n целых чисел. Определить среднее арифметическое n введенных чисел.

Программа 8.8.4
i, s = 0, 0
n = int(input('n = '))
while i < n:
    print(f'd_{i + 1} = ', end='')
    d = float(input())
    i = i + 1 # или i += 1
    s = s + d # или s += d
else:
    s = s / i # или s /= i
    print(f's = {s:.3f}')

Вывод

n = 5
d_1 = 1.12
d_2 = 2.03
d_3 = 3.55
d_4 = 3.71
d_5 = 4.22
s = 2.926

На самом деле, в подобных задачах счетчик не так уж и нужен! Действительно, если известно общее количество шагов цикла n, то мы можем уменьшать значение n с каждым шагом цикла на единицу до тех пор, пока значение n не станет равным 0 (если, конечно, начальное значение n больше в программе не потребуется). Сформулировав логическое выражение сравнения n с 0, мы можем создать условие выхода из цикла.
Задача 5. Составьте программу рисования n квадратов c общим центром и шагом (расстояние между сторонами квадратов) равным d.

Программа 8.8.5
import turtle as t
##################### Параметры холста ######################
w = t.Screen()
w.reset()
w.title('Квадраты')
w.bgcolor('black')
w.setup(width = 600, height = 600, startx = -10, starty = 10)
#################### Параметры черепахи #####################
t.speed(10)
t.color('red')
t.pensize(2)
###################### Решение задачи #######################
n = int(input('n = ')) # Число квадратов
d = int(input('d = ')) # Шаг
r = d # Длина стороны квадрата
x, y = 0, 0 # Начальная позиция черепахи
while n > 0:  
    x -= 10 # Устанавливаем
    y -= 10 # новые координаты и
    t.up()
    t.goto(x, y) # смещаемся по гипотенузе
    t.down()
    t.fd(r)      # Рисуем квадрат
    t.lt(90)
    t.fd(r)
    t.lt(90)
    t.fd(r)
    t.lt(90)
    t.fd(r)
    t.lt(90)
    r += 2 * d  # Увеличиваем сторону и
    n -= 1      # переходим к рисованию следующего
w.exitonclick() # Выход по клику мыши на холсте
t.mainloop()    # Задержка холста

Вывод

Параметры: n = 20, d = 10

Счетчик с произвольным шагом

В программах выше использовался счетчик с целочисленным шагом равным единице для определения количества шагов цикла. Но, в общем случае, счетчик может иметь произвольный шаг, в том числе дробный. Покажем это на примере.
Задача 6. Составить программу вывода таблицы значений квадратного корня чисел от 0.2 до 10.0 с шагом 0.2 и точностью до 4 знаков после запятой.

Программа 8.8.6
from math import sqrt
i = 0.0
print('=====================================')
print('||  d -> sqrt(d) ||   d -> sqrt(d) ||')
print('=====================================')
while i < 5:
    i += 0.2
    print(f'|| {i:.1f} -> {sqrt(i):.4f} || \
    {i + 5:>4.1f} -> {sqrt(i + 5):.4f} ||')
print('=====================================')

Вывод

=====================================
||  d -> sqrt(d) ||   d -> sqrt(d) ||
=====================================
|| 0.2 -> 0.4472 ||  5.2 -> 2.2804 ||
|| 0.4 -> 0.6325 ||  5.4 -> 2.3238 ||
|| 0.6 -> 0.7746 ||  5.6 -> 2.3664 ||
|| 0.8 -> 0.8944 ||  5.8 -> 2.4083 ||
|| 1.0 -> 1.0000 ||  6.0 -> 2.4495 ||
|| 1.2 -> 1.0954 ||  6.2 -> 2.4900 ||
|| 1.4 -> 1.1832 ||  6.4 -> 2.5298 ||
|| 1.6 -> 1.2649 ||  6.6 -> 2.5690 ||
|| 1.8 -> 1.3416 ||  6.8 -> 2.6077 ||
|| 2.0 -> 1.4142 ||  7.0 -> 2.6458 ||
|| 2.2 -> 1.4832 ||  7.2 -> 2.6833 ||
|| 2.4 -> 1.5492 ||  7.4 -> 2.7203 ||
|| 2.6 -> 1.6125 ||  7.6 -> 2.7568 ||
|| 2.8 -> 1.6733 ||  7.8 -> 2.7928 ||
|| 3.0 -> 1.7321 ||  8.0 -> 2.8284 ||
|| 3.2 -> 1.7889 ||  8.2 -> 2.8636 ||
|| 3.4 -> 1.8439 ||  8.4 -> 2.8983 ||
|| 3.6 -> 1.8974 ||  8.6 -> 2.9326 ||
|| 3.8 -> 1.9494 ||  8.8 -> 2.9665 ||
|| 4.0 -> 2.0000 ||  9.0 -> 3.0000 ||
|| 4.2 -> 2.0494 ||  9.2 -> 3.0332 ||
|| 4.4 -> 2.0976 ||  9.4 -> 3.0659 ||
|| 4.6 -> 2.1448 ||  9.6 -> 3.0984 ||
|| 4.8 -> 2.1909 ||  9.8 -> 3.1305 ||
|| 5.0 -> 2.2361 || 10.0 -> 3.1623 ||
=====================================

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

Программа 8.8.7
#################### Параметры черепахи #####################
import turtle as t
w = t.Screen()
w.reset()
w.title('Парабола')
w.bgcolor('black')
w.setup(width = 600, height = 600, startx = -10, starty = 10)
t.speed(10)
###################### Решение задачи #######################
x = -25
while x < 25:
    y = x ** 2 - 280  # Вершина в т. (0; -280)
    t.up()
    t.goto(10 * x, y) # Делаем ветви широкими
    t.down()
    t.dot(3, 'green2')
    x += 0.3
w.exitonclick() 
t.mainloop()   

Вывод

Проход циклом по разрядам числа

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

Программа 8.8.8
n = int(input('n = '))
d = 0
while n > 0:
    d = d * 10 + n % 10
    n //= 10
else:
    print(d)

Вывод

n = 123456
654321

Одна из задач такого рода – это перевод числа из 10 системы счисления (далее – с.с.) в с.с. по основанию q.
Задача 8. Дано цело десятичное число n. Перевести это число в с.с. с основанием q (целое число в интервале 2..9)

Программа 8.8.9
n = int(input('n = '))
q = int(input('q = '))
d = 0
p = 1
while n > 0:
    d += n % q * p
    p *= 10
    n //= q
else:
    print(d)

Вывод

n = 2021
q = 2
11111100101
-------------------
n = 2021
q = 3
2202212

Идея алгоритма основана на способе “деления” описанного здесь. Суть его заключается в следующем. Исходное число делим на основание с.с. и получаем остатки от этого деления в цикле. Первый остаток – это младший разряд q-ичного числа. Последний – старший разряд. Для того, чтобы повысить старшинство разряда, мы умножаем полученный в каждом шаге цикла остаток на значение переменной p, которое, с каждым шагом цикла, возрастает в 10 раз. Само же число получаем в накопителе суммы – d (т. е. фактически мы производим расчеты в 10 с.с.). Встроенные возможности языка по переводу чисел в с.с. по основаниям 2..36 описаны нами ранее.

Приложение

Примеры решения задач
Вопросы
Темы сообщений
Задания А
Задания Б
Задания С
Ссылки
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (4 оценок, среднее: 4,25 из 5)
Загрузка...

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Обсуждение закрыто.