0:00
[БЕЗ_ЗВУКА] В предыдущем видео мы с вами изучили,
какие операции можно выполнять с типами, которые хранят одно значение.
Теперь давайте посмотрим, что можно делать с контейнерами — с типами,
которые хранят больше, чем одно значение.
Какая операция самая простая для контейнера?
Это, я думаю, перебрать все элементы этого контейнера и что-то с ними сделать.
Например, давайте возьмем какую-то строку s и запишем в нее
какие-нибудь символы, допустим abcdef g.
Чтобы перебрать все эти символы и что-то с ними сделать,
нужно написать вот такой простой цикл: for (char c : s).
И внутри него мы, например,
можем вывести символы строки через запятую.
Вот таким простым образом.
Компилируем эту программу, она у нас компилируется, запускаем — и видим,
что символы нашей строки действительно вывелись через запятую.
Правда, тут ввиду простоты реализации и после последнего символа идет запятая,
но ничего страшного — для нашей цели это подойдет.
Собственно, вы видите: вот таким образом мы можем обратиться к
каждому символу строки.
Таким же образом мы можем перебрать все элементы вектора.
Например, объявляем вектор
целых чисел: vector<int> nums.
И, допустим, записываем в него какие-то числа.
Дальше мы меняем наш цикл.
Так как у нас вектор хранит элементы типа int,
то для переменной цикла мы также должны задать тип int.
Ну и строки s у нас больше нет, а есть вектор nums.
Поэтому указываем его в цикле.
Компилируем, запускаем и видим,
что в консоли появились числа, которые мы записали в наш вектор.
Собственно, вот таким вот образом мы можем
вывести все элементы нашего вектора.
При этом я хочу обратить ваше внимание на такой момент: мы когда меняли
строку на вектор int'ов, то из-за того,
что тип элемента поменялся с char на int, нам пришлось внутри
цикла также поменять тип счетчика с char на int.
Это, может быть, неудобно, потому что надо помнить,
что его надо поменять в двух местах.
И в C++ есть средство, чтобы избежать такого дублирования.
Для этого вместо типа, конкретного типа, здесь нужно написать auto,
тогда компилятор будет сам догадываться, какой тип будет иметь этот счетчик.
Например, давайте возьмем наш вектор int'ов и заменим его на вектор строк.
И превратим числа в списки инициализации, в строки.
Даже в последнем сделаем 5+.
Вы видите, что здесь написано auto.
Мы компилируем нашу программу, она компилируется.
Запускаем и видим, что все продолжает работать,
также содержимое нашего вектора было выведено.
Таким образом, мы можем использовать ключевое слово auto в циклах,
который перебирает все элементы контейнера,
чтобы не дублировать тип элементов этого контейнера.
Прекрасно.
Мы только что узнали, как перебирать все элементы контейнера.
Что еще можно делать с контейнерами?
Например, давайте вернем вектор
целых чисел и поставим перед собой такую задачу.
Давайте мы посчитаем, сколько в нашем векторе nums пятерок.
Как мы это можем написать?
Мы можем написать, объявить переменную, которая,
собственно, посчитает нам, сколько там пятерок.
Перебрать все элементы нашего вектора nums и проверить,
что если очередной элемент равен пятерке,
то увеличиваем quantity на 1.
И в конце вывести сообщение
[ШУМ] с тем,
сколько у нас пятерок в векторе.
Давайте проверим, что мы нигде не ошиблись, программа компилируется.
Запустим ее, видим, что программа вывела, что пятерок две.
Их действительно две.
И задумаемся о такой вещи: мы с вами только что написали — раз, два,
три, четыре, пять, шесть — шесть строчек кода лишь для того, чтобы посчитать,
сколько в векторе пятерок.
Это как-то многовато.
Так вот, в C++ писать такие длинные программы для таких простых вещей
необязательно, потому что в этом языке есть очень богатая библиотека алгоритмов,
позволяющая подобные задачи решать в одну строчку.
Чтобы воспользоваться этой библиотекой,
нужно подключить заголовочный файл algorithm.
И тогда количество пятерок можно посчитать вот такой простой
командой: quantity = count (begin
(nums), end(nums), 5).
Этот наш самописный цикл становится не нужен.
Компилируем нашу программу, запускаем и видим,
что она продолжает работать правильно.
Собственно, здесь нужно сказать, что такое begin и end.
Это специальный способ задать
последовательность в библиотеке алгоритмов C++.
Мы далее в нашем курсе будем подробно рассказывать вам,
что это такое и как это все внутри устроено и как работает.
Сейчас же просто скажем, что функция count, которую мы, собственно,
взяли из библиотеки algorithm, принимает последовательность и позволяет
искать количество указанных значений в этой последовательности.
Что еще умеет делать библиотека algorithm.
Она упрощает такой часто необходимый алгоритм, как сортировку.
Собственно, чтобы отсортировать наш вектор,
нужно просто написать sort (begin(nums), end(nums)).
Давайте выведем содержимое нашего вектора
после сортировки, чтобы убедиться, что он действительно сортируется.
Программа компилируется,
работает и выводит содержимое вектора в порядке возрастания.
Собственно, вот буквально одной строчкой мы сделали то,
что смогли отсортировать наш вектор.
Ну и опять же сортировка работает независимо от типа вектора.
Мы можем поменять int на string и, например,
положить в вектор какие-нибудь слова,
например, hello, world и,
например, milk.
Скомпилируем, запустим,
видим, что слова milk и world поменялись
местами и все три слова теперь у нас отсортированы в алфавитном порядке.
Давайте подведем итоги.
В этом видео мы с вами познакомились с операциями,
которые можно выполнять над контейнерами.
Мы узнали, как перебирать все элементы контейнера, узнали о существовании
библиотеки algorithm и познакомились с весьма полезными алгоритмами sort и count.