0:00
[БЕЗ_ЗВУКА] Давайте
рассмотрим другие примеры циклов, которые есть в C++.
Например, нам может потребоваться не проверка условия,
а перебор некоторого набора значений.
В качестве набора значений мы можем использовать некоторые контейнеры.
Давайте попробуем воспользоваться контейнером «вектор».
Для этого допишем недостающий заголовочный файл
и объявим наш вектор,
заранее его проинициализировав некоторыми числами.
Пусть вектор будет числовой.
[БЕЗ_ЗВУКА] И попробуем решить аналогичную задачу.
Просуммируем все числа, которые есть в нашем векторе.
Как это удобнее всего сделать?
Удобнее всего воспользоваться так называемым циклом range-based for.
Как он записывается?
Что же он делает?
Во-первых, идет ключевое слово for,
затем следуют круглые скобки, внутри которых записывается следующая
конструкция: пишется ключевое слово auto, затем идет название переменной,
которая будет символизировать очередное значение внутри нашего вектора.
Пусть это будет i.
И дальше идет двоеточие, после него идет сам вектор.
Или любой другой контейнер, который мы захотим
перебрать.
Нам по-прежнему нужна внешняя переменная для сохранения суммы.
И в отличие от цикла while,
нам с переменной i внутри range-based for ничего делать не нужно.
Она сама будет перемещаться по всем значениям вектора.
Давайте мы в конце выведем значение суммы для пользователя.
Запускаем программу.
У нас получилось число 29.
Давайте просуммируем, что же у нас в нашем векторе.
10, 4 плюс 6 — 20; плюс 8 и плюс 1 — 29.
Все верно.
Следует обратить внимание,
что range-based for очень хорошо подходят не только для вектора,
но и для произвольных контейнеров.
Давайте попробуем другой контейнер.
Например, контейнер map.
Я напомню, что контейнер map позволяет сохранять
некоторое отображение из одного произвольного типа в другой.
Давайте сделаем отображение из строк в числа.
Для строк нам потребуется еще один заголовочный файл.
Также напомню, что контейнер map инициализируется
следующим образом: сначала идет пара внешних фигурных скобок,
и затем внутри записывается в фигурных скобках пара значений.
Давайте мы проинициализируем его очень просто.
Запишем первые три буквы алфавита, первые три числа.
1 2 3.
[БЕЗ_ЗВУКА] Внутри нашего
цикла мы сделаем довольно простую операцию.
Мы выведем на одной строке
конкатенацию всех значений строк в нашей карте,
а во второй строке мы выведем сумму всех чисел, которые соответствуют этим строкам.
Для суммы мы по-прежнему оставляем внешнюю переменную,
а для конкатенации строк мы заведем новую.
[БЕЗ_ЗВУКА] Для
того чтобы получить доступ
к строке в нашей карте, то есть к первому элементу из пары,
необходимо написать следующее выражение: мы пишем переменную,
которая следует после ключевого слова auto, ставим точку и пишем слово first.
Таким образом мы получем строку.
Прибавляем к предыдущему значению.
Для того чтобы получить доступ к второму элементу из пар внутри map,
мы пишем аналогичную конструкцию, только вместо слова first мы пишем слово second.
Давайте в конце мы выведем,
что же у нас получилось, на экран.
Не забываем про оператор переноса строки.
Теперь попробуем запустить нашу программу.
Хотя нет, конечно же,
нужно исправить значение контейнера внутри range-based for.
Мы хотим пройтись не по вектору, а по нашей новой карте.
Заменим переменную a на переменную b и запустим нашу программу.
Все верно.
В первой строчке мы получили конкатенацию, во второй мы получили сумму.
По каким еще контейнерам можно пройтись range-based for?
Можно пройтись по строке.
Давайте попробуем решить следующую задачу на примере строки.
Мы будем выводить номера символов в строке,
которые равны букве a.
Удаляем предыдущий код и
запишем произвольную строчку,
конечно же, не забывая про символ a.
Для того чтобы выводить позицию символа,
нам потребуется внешняя переменная, в которой мы будем его сохранять.
Назовем внутреннюю переменную по-другому,
так как переменная i у нас теперь используется для других целей.
И что же мы будем делать?
Мы будем сравнивать очередной символ с буквой a.
Если символ равен,
то мы выводим текущее значение нашего индекса.
Если нет, то мы ничего не делаем.
И в любом случае мы увеличиваем значение индекса.
Давайте убедимся, что программа работает.
Да, у нас буква a встречается каждые четыре символа: в нулевой,
в четвертой и в восьмой позиции.
Обратим внимание, что мы начали отсчет с нуля.
На самом деле цикл range-based for
для подобного рода задач не очень удобен.
Под классом задач имеются в виду задачи, в которых
мы хотим считать некоторое внешнее число и сохранять порядок или позицию.
Для этого есть другой вариант цикла for,
который специально для этого и предназначен.
Давайте попробуем решить нашу задачу с помощью простого цикла for.
Записывается он следующим образом: также следует сначала ключевое слово for,
затем круглые скобки и фигурные скобки, внутри которых мы запишем тело цикла.
Но главное отличие в том, что мы пишем внутри круглых скобок.
Для простого цикла for
внутри круглых скобок есть три различные секции.
Первая секция подразумевает инициализацию.
В ней мы инициализируем переменную, которая будет символизировать индекс.
После этого мы ставим точку с запятой.
Во второй секции мы записываем условие, согласно которому цикл for
будет по-прежнему продолжать выполняться.
В этом он очень похож на цикл while.
В нашем случае мы будем сравнивать
значение индекса с размером строки, чтобы пройтись по всем ее элементам.
После этого также следует точка с запятой,
и в третьей секции мы записываем так называемую операцию,
выполняющуюся после тела цикла.
В нашем случае мы будем увеличивать значение индекса.
Внутри тела цикла мы по-прежнему будем сравнивать очередное значение
символа в строке с буквой a, только запись будет выглядеть несколько иначе.
[БЕЗ_ЗВУКА] Если
наш символ совпадает с буквой a, мы будем выводить текущее значение индекса.
И не забываем про перевод строки, чтобы все индексы оказались в разных строках.
Давайте запустим нашу программу.
Мы получили точно такой же результат — 0, 4 и 8.