Реализовать цикл со счетчиком
Конец цикла со счетчиком и условием
В Python я могу реализовать цикл со счетчиком шагов и условием остановки как классический случай для цикла :
где fun(x) — произвольная функция от целых до целых.
Я всегда сомневаюсь, что это лучший способ его кодирования ( Pythonically , и с точки зрения удобочитаемость и эффективность ) или лучше запустить его как цикл while :
какой подход лучше? В частности — я обеспокоен использованием оператора break , который не кажется правильным.
Цикл for несколько более производительный, чем while , потому что range() реализована в C , в то время как операция += интерпретируется и требует больше операций и создания/уничтожения объекта. Вы можете проиллюстрировать разницу в производительности с помощью модуля timeit , например:
Цикл for , вероятно, более Pythonic в подавляющем большинстве случаев, когда вы хотите перебрать итерируемый объект . Кроме того, чтобы процитировать Python wiki : «Поскольку цикл for в Python настолько мощный, но редко используется, за исключением случаев, когда требуется ввод пользователя». Нет ничего непонятного в использовании оператора break per se.
Читаемость в основном субъективна, я бы сказал, что цикл for также более читабелен, но, вероятно, это зависит от вашего предыдущего опыта программирования.
Существует небольшая разница в производительности. Поскольку цикл while выполняет дополнительную логическую проверку на каждой итерации, он немного медленнее.
Однако для большинства функций, которые вы хотели бы оценить, существует альтернатива использованию цикла, во-первых, который намного быстрее. Смотрите пример ниже. И я уверен, что есть более оптимальные реализации ..
прошедшее время 11.082087516784668
а вот 14.429940938949585
Однако, если вы хотите/должны использовать цикл, цикл for является, как правило, более подходящим для Pythonic способом, как объясняется в этом приятном ответе на связанный вопрос
Правка: Ответ Криса Рэндса ниже объясняет это с точки зрения C-кода и использует более точный (хотя на таких макроуровнях, как я сделал этот пример, что не имеет большого значения) модуль синхронизации. Прочитайте и его ответ.
лучшим способом было бы вообще не зацикливаться. itertools для спасения:
+ это было бы намного быстрее, чем зацикливание
Если рассматривать только байт-код, цикл while получил 30 строк, а цикл for получил 26 строк.
В конце концов, не думаю, что это так важно, но я лично предпочитаю версию для цикла, так как ее легче читать.
Код, который я использовал:
Я почти уверен, что вам не нужно заботиться о производительности, когда вы сравниваете циклы while и for , поэтому главный вопрос касается читабельности.
в первую очередь, конечно
намного лучше чем
потому что вам не нужно помнить некоторые C-подобные переменные, когда вы читаете простой цикл
Решение @ quidkid довольно элегантно, но это хороший момент, который
работает только на довольно простых примерах и потеряет читабельность, так как вам потребуется добавить некоторые дополнительные функции
Как я вижу, основная проблема в вашем коде заключается в том, что ваша функция не чистая, поэтому, возможно, вы должны сделать что-то вроде этого:
Используя функциональный подход, создайте локальное замыкание, которое выполняет действие и возвращает значение предиката завершения. Затем итерируйте по входам, пока не закончите.
Другой способ завершить последовательность действий:
Похоже, мы вернулись к выражению break для pythonicness
Если вы ищете эффективность, используйте функции генератора.
Результат% timeit в ipython
Самый медленный пробег длился в 6,15 раза дольше самого быстрого. Это могло, это может означает, что промежуточный результат кэшируется. 10000 петель, лучше всего 3: 30,9 мкс на петлю
Конец цикла со счетчиком и условием
В Python я могу реализовать цикл с счетчиком шагов и условием остановки как классический случай цикла for:
где fun(x) некоторая произвольная функция от целых чисел до целых чисел.
Я всегда сомневаюсь, что это лучший способ его кодирования (Python, с точки зрения читабельности и эффективности) или лучше запустить его как цикл while:
какой подход лучше? В частности — я обеспокоен использованием break утверждение, которое не кажется правильным.
8 ответов
for цикл немного более производительный, чем while так как range() реализуется в C, а += операция интерпретируется и требует больше операций и создания / уничтожения объекта. Вы можете проиллюстрировать разницу в производительности, используя timeit модуль, например:
for цикл, возможно, более Pythonic в подавляющем большинстве случаев, когда вы хотите перебрать итерируемый объект. Кроме того, процитирую вики Python: «Поскольку цикл for в Python настолько мощный, но редко используется, за исключением случаев, когда требуется ввод данных пользователем». Нет ничего непонятного в использовании break заявление само по себе.
Читаемость в основном субъективна, я бы сказал, for Цикл также более читабелен, но, вероятно, зависит от вашего предыдущего опыта программирования.
Существует небольшая разница в производительности. Поскольку цикл while выполняет дополнительную логическую проверку на каждой итерации, он немного медленнее.
Однако для большинства функций, которые вы хотели бы оценить, существует альтернатива использованию цикла, во-первых, который намного быстрее. Смотрите пример ниже. И я уверен, что есть более оптимальные реализации..
прошедшее время 11.082087516784668
а вот 14.429940938949585
Однако, если вы хотите / должны использовать цикл, цикл for в целом является более подходящим для Pythonic способом, как объясняется в этом хорошем ответе на связанный вопрос.
РЕДАКТИРОВАТЬ: Ответ Криса Рэндса ниже объясняет это с точки зрения C-кода и использует более точный (хотя на таких макроуровнях, как я предполагал, что этот пример, который не будет иметь большого значения) модуль синхронизации. Прочитайте и его ответ.
Лучшим способом было бы вообще не зацикливаться. itertools для спасения:
+ это было бы намного быстрее, чем зацикливание
Если рассматривать только байт-код, цикл while получил 30 строк, а цикл for получил 26 строк.
В конце концов, не думаю, что это так важно, но я лично предпочитаю версию для цикла, так как ее легче читать.
Код, который я использовал:
Я уверен, что вам не нужно заботиться о производительности, когда вы сравниваете циклы while и for, поэтому главный вопрос — о читабельности.
в первую очередь, конечно
намного лучше чем
потому что вам не нужно помнить некоторые C-подобные переменные, когда вы читаете простой цикл
Решение @quidkid довольно элегантно, но это хороший момент, который
работает только на довольно простых примерах и потеряет читабельность, так как вам потребуется добавить некоторые дополнительные функции
Как я вижу, основная проблема в вашем коде заключается в том, что ваша функция не чистая, поэтому, возможно, вам следует сделать что-то вроде этого:
2. Операторы цикла
Операторы цикла
Операторы цикла используются для организации многократно повторяющихся вычислений. Любой цикл состоит из тела цикла, то есть тех операторов, которые выполняются несколько раз, начальных установок, модификации параметров цикла и проверки условия продолжения выполнения цикла (рис. 3.1). Выше было показано, как реализовать цикл с помощью двух операторов if и goto. Операторы цикла позволяют организовать цикл «явным» образом, что способствует большей оптимизации программного кода.
Переменные, изменяющиеся в теле цикла и используемые при проверке условия продолжения, называются параметрами цикла. Целочисленные параметры цикла, изменяющиеся с постоянным шагом на каждой итерации, называются счетчиками цикла.
Начальные установки могут явно не присутствовать в программе, их смысл состоит в том, чтобы до входа в цикл задать значения переменным, которые в нем используются.
Цикл завершается, если условие его продолжения не выполняется. Воз-можно принудительное завершение, как текущей итерации, так и цикла в целом. Для этого служат операторы break, continue, и goto. Передавать управление извне внутрь тела цикла, минуя его заголовок, не рекомендуется, так как параметры цикла могут быть не определены.
Для удобства, а не по необходимости, в C++ есть три разных оператора цикла – while, do while и for.
Цикл с предусловием (while)
Цикл с предусловием реализует структурную схему, приведенную на рис. 3.1, а, и имеет вид:
while ( выражение ) оператор
Выражение определяет условие повторения тела цикла, представленного простым или составным оператором. Выполнение цикла начинается с вычисления выражения. Если оно истинно (не равно false), выполняется оператор цикла. Если при первой проверке выражение равно false, цикл не выполнится ни разу. Тип выражения должен быть арифметическим или приводимым к нему. Выражение вычисляется перед каждой итерацией цикла. Когда выражение оказывается ложным, управление передается следующему после цикла оператору.
Тело цикла может состоять не из одного оператора, а представлять собой блок.
Пример (программа находит все делители целого положительного числа):
Для краткости изложения начало всех программ этой главы не приводится, но подразумевается
int num;
cout > num;
int div = 2; // кандидат на делитель
while (div
Для краткости изложения начало всех программ этой главы не приводится, но подразумевается, что оно включает функцию RUS, известную из предыдущих примеров, а также необходимые директивы и библиотеки.
Цикл с постусловием (do … while)
Цикл с постусловием реализует структурную схему, приведенную на рис. 3.1, б, и имеет вид:
do оператор while (выражение);
Сначала выполняется оператор или блок, составляющий тело цикла, а затем вычисляется выражение. Если оно истинно (не равно false), тело цикла выполняется еще раз. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления. Тип выражения должен быть арифметическим или приводимым к нему.
Пример (программа осуществляет проверку ввода):
char answer;
do
while (answer != ‘y’);
Цикл с параметром for
Цикл имеет следующий формат:
for ( инициализация; выражение; модификации) оператор;
Инициализация используется для объявления и присвоения начальных значений величинам, используемым в цикле. В этой части можно записать не-сколько операторов, разделенных запятой (операцией «последовательное выполнение»), например, так:
for (int i = 0, j = 2; .
или
int k, m:
for (k = 1, m = 0; .
Областью действия переменных, объявленных в части инициализации цикла, является цикл. Инициализация выполняется один раз вначале исполнения цикла.
Выражение определяет условие выполнения цикла: если его результат, приведенный к типу bool, равен true, цикл выполняется, иначе происходит выход из цикла и управление передается следующему за оператором цикла оператору. Цикл реализован как цикл с предусловием: сначала проверяется условие «на истинность», затем выполняется оператор (тело цикла), затем производятся модификации, после чего управление возвращается к проверке условия «на истинность» и т.д.
Модификации выполняются после каждой итерации цикла и служат для изменения управляющих переменных цикла (параметров цикла). В части модификаций можно записать несколько операторов через запятую. Обычно здесь записывается модификация счетчика цикла. Пример (оператор, вычисляющий сумму чисел от 1 до 100):
for (int i = 1, s = 0; i
Здесь i – счетчик цикла. Он инициализируется значением 1. В начале каждой итерации проверяется, не достиг ли он значения 100. Как только i станет равным 101, оператор s+= i пропускается и управление передается следующему за оператором цикла оператору. В конце каждой итерации i увеличивается на 1 ( операция i++).
Оператор в структуре цикла for может быть простым оператором или блоком.
Любая из частей оператора for может быть опущена, но точки с запятой надо оставить на своих местах. Поэтому пример бесконечного цикла for выглядит следующим образом:
Пример (программа печатает таблицу значений функции у=х2+1 во введенном диапазоне):
float Xn, Xk, Dx, X;
printf(RUS(«Введите диапазон и шаг изменения аргумента: «));
scanf(«%f%f%f», &Xn, &Xk, &Dx);
printf(«| X | Y |n»);
for (X = Xn; X
Часто встречающиеся ошибки при программировании циклов – использование в теле цикла неинициализированных переменных и неверная запись условия выхода из цикла.
Чтобы избежать ошибок, рекомендуется:
— проверить, всем ли переменным, встречающимся в правой части операторов присваивания в теле цикла, присвоены до этого начальные значения (а также возможно ли выполнение других операторов);
— проверить, изменяется ли в цикле хотя бы одна переменная, входящая в условие выхода из цикла;
— предусмотреть аварийный выход из цикла по достижению не-которого количества итераций;
— если в теле цикла требуется выполнить более одного оператора, нужно заключать их в фигурные скобки;
— при программировании цикла for не допускать изменение значения счетчика в теле цикла. Это может приводить к » выпадению » итераций или к бесконечному циклу.
В блок-схемах цикл с параметром for можно изображать с использованием блока «модификация». Внутри блока записывается начальное значение, конечное значение и шаг изменения параметра (рис. 3.2). Если шаг равен 1, его можно не указывать.
Операторы цикла взаимозаменяемы, но можно привести некоторые рекомендации по выбору наилучшего в каждом конкретном случае.
Оператор do … while обычно используют, когда цикл требуется обязательно выполнить хотя бы раз (например, если в цикле производится ввод данных).
Оператором while удобнее пользоваться в случаях, когда число итераций заранее не известно, очевидных параметров цикла нет или модификацию параметров удобнее записывать не в конце тела цикла.
Оператор for предпочтительнее использовать в большинстве остальных случаев (однозначно – для организации циклов со счетчиками).
Школе NET
- Колесо Фортуны
- через Вконтакте
Register
Do you already have an account? Login
Login
Don’t you have an account yet? Register
Newsletter
Submit to our newsletter to receive exclusive stories delivered to you inbox!
- Главная
- Вопросы & Ответы
- Вопрос 3912251
Суррикат Мими
-Классификация Алгоритмов(структура,без определений)Сделать математическую постановку задачи,нарисовать блок-схему и таблицу расччетов:Цикл со счетчиком:Вычислить сумму четных чисел от 12 до 30
Лучший ответ:
Мари Умняшка
1. Алгоритмы бывают линейные, разветвляющиеся (содержащие условия), циклические (содержащие циклы) и комбинированные (объединяющие в себе несколько из перечисленных выше алгоритмов). Несколько особняком стоят рекурсивные алгоритмы. Это алгоритмы, которые повторно обращаются сами к себе. Рекурсивный алгоритм может быть сведен к комбинированному, но в некоторых случаях процесс сведения оказывается трудоемким, а сам алгоритм теряет свою наглядность.
2. Цикл со счетчиком относится к циклическим алгоритмам. Управляет циклом специальная переменная, которая называется счетчиком или параметром цикла. Особенность такого цикла в том, что он всегда выполняется известное число раз, которое определяется заголовком цикла до первого входа в тело цикла. Цикл со счетчиком обеспечивает изменение параметра цикла от некоторого начального значения a до значения b c шагом h. Количество повторений такого цикла вычисляется по формуле
, где первое слагаемое округляется до ближайшего меньшего целого. Если n≤0, цикл не выполняется ни разу.
3. В языке Паскаль цикл со счетчиком накладывает весьма жесткие условия на параметр цикла (счетчик):
— параметр цикла должен быть целочисленной переменной;
— шаг изменения параметра цикла может быть равен или 1, или -1;
— значения границ интервала (a,b) и шага h фиксируются перед первым входом в тело цикла и даже будучи измененными в теле цикла уже не влияют на параметр цикла;
— значение параметра цикла нельзя изменять в теле цикла;
— значение параметра цикла после выхода из цикла считается неопределенным, т.е. не должно использоваться в случае тиражирования исходного кода программы, поскольку в разных реализациях Паскаля это значение может оказать различным- любым, равным последнему допустимому в теле цикла значению, либо отличающимся от этого значение на величину шага в сторону изменения параметра цикла.
4. Реализация поставленной задачи.
Число считается четным, если оно делится на 2 без остатка. Нам нужно найти сумму четных чисел из ряда 12, 14, 16, . 28, 30. Цикл со счетчиком, как было замечено выше, не может обеспечить изменение параметра цикла с шагом два. Поэтому есть три пути.
Первый путь — организовать цикл со счетчиком, который переберет все числа от 12 до 30. В теле цикла проверять условие четности и удовлетворяющие этому условию числа передавать не суммирование.
Второй путь — найти формулу для общего члена последовательности чисел и реализовать её при изменении счетчика с шагом 1. Формула для получения четных числ натурального ряда известна: m=2*k, где k=1,2,3.
Если мы будем менять k от 6 до 15, то получим набор целых четных чисел m от 12 до 30.
Третий путь — вспомнить формулу суммы ряда арифметической прогрессии.
На этом, третьем пути, мы легко нашли ответ и программа получается не нужна.
Тем не менее, в задании сказано реализовать цикл со счетчиком и мы выбираем второй путь, как более эффективный.
5. Программа на языке Pascal
var
i, s: integer;
begin
s := 0;
for i := 6 to 15 do s := s + 2 * i;
Writeln(‘Сумма четных чисел от 12 до 30 равна ‘, s)
end.
Результат выполнения:
Сумма четных чисел от 12 до 30 равна 210
Операторы цикла
Теоретический материал (Паскаль)
В цикле со счетчиком тело цикла повторяется заранее определенное число раз. Циклы со счетчиком используются довольно часто, и поэтому в языке Паскаль для этих целей имеется специальная конструкция.
Можно, конечно, циклы со счетчиком моделировать при помощи операторов while и Repeat, но структура цикла со счетчиком проще.
Общая форма записи цикла со счетчиком
for i := A to B do begin . . . end; |
for i := A downto B do begin . . . end; |
Здесь переменная i — управляющая переменная или переменная цикла,
А — начальное значение переменной цикла,
В — конечное значение переменной цикла.
При переходе к обработке оператора цикла for управляющей переменной присваивается заданное начальное значение. Затем в цикле выполняется исполнительный оператор (или составной оператор). Каждый раз при выполнении исполнительного оператора управляющая переменная увеличивается на 1 (для for. to) или уменьшается на 1 (для for. downto). Цикл завершается при достижении управляющей переменной своего конечного значения.
1) for i := 1 to ListSize do begin readln (Number): S := S +Number; end; |
2) for Dlina := 15 downto 1 do writeln (Sqr(Dlina)); |
3) for x := 1 to 10 do for y := 1 to 10 do writeln (x,’*’,y,’=’,x*y); |
4) for Range := Number+1 to Multi*3 do writeln (Sqrt(Range)); |
При использовании цикла for компьютер выполняет за программиста черновую работу по инициализации управляющей переменной и по ее увеличению (уменьшению) при каждом повторении цикла. Единственное ограничение заключается в том, что тип управляющей переменной не должен быть real. Переменная цикла не должна изменяться какими-либо операторами внутри цикла. К ней можно обращаться и использовать в вычислениях, но нельзя присваивать новое значение. Присваивания могут выполняться только механизмом самого цикла. Таким образом, следующий цикл является некорректным:
for i := 1 to 10 do begin . . . i := i-1; . . . end; |
Управляющая переменная должна описываться, как и любая другая переменная. Обычно переменная цикла имеет тип integer, но позднее Вы рассмотрите другие типы данных, которые могут указываться в качестве типа управляющей переменной.
Внимание! Следует помнить, что управляющая переменная не может быть типа real.
Исполнительная часть цикла может быть либо простым, либо составным оператором. Если начальное значение цикла for . to больше конечного значения, то никакие операции не выполнятся. Таким образом, следующий оператор не приведет ни к каким действиям
for j := 1 to 0 do writeln (j); |
Однако цикл, представленный в такой форме, распечатает целые числа от единицы до десяти:
for j := 1 to 10 do writeln (j); |
Как можно догадаться, следующий цикл выполняет счет в обратном порядке:
for j := 10 downto 1 do writeln (j); |
Часто тело цикла For содержит еще один оператор цикла For. Структуры такого рода называются вложенными циклами. При завершении внутреннего цикла управляющая переменная внешнего цикла увеличивается. Повторение этих действий будет продолжаться до завершения внешнего цикла. Приведенный ниже вложенный цикл печатает пары чисел, начиная от (1,1), (1,2). и кончая (10,10):
for х:= 1 to 10 do for у:= 1 to 10 do writeln (‘(‘,х,’,’,y,’), ‘); |
Задание. Выполните две задачи, уже решенные Вами задачи с помощью других видов цикла, с помощью со счетчиком.