[БЕЗ СЛОВ] Итак, мы рассмотрели словари, которые позволяют хранить пары «ключ, значение». Давайте рассмотрим такой пример: мы захотим сохранить для каждого человека, является ли он известным. Наверное, в этом случае я заведу словарь, у которого ключами будут строки, а значениями – признаки, является ли человек известным, то есть bool, и назову его is_famous_person. Если теперь я захочу указать, что какие-то люди являются известными, например, бесспорно, Страуструп является известным человеком, я напишу is_famous_person["Stroustrup"] = true, ну и, скажем, Деннис Ритчи тоже должен оказаться в этом словаре. Я получил словарь. Словарь, у которого ключами являются строчки, а значениями являются булевские значения. В данном случае они всегда true. Захочу ли я добавлять в этот словарь людей, которые являются неизвестными? Наверное, нет. Их же очень много! Зачем мне их хранить, если я могу хранить только тех, кто является известными? Хорошо, тогда у меня в словаре значения всегда будут только true. Вопрос: зачем мне хранить эти значения? Наверное, нет. Наверное, я не хотел сохранить словарь, у которого ключ – какая-то осмысленная строчка, а значение – просто true. Наверное, речь все-таки идет о множестве людей, которые являются известными. Давайте я тогда использую для этого подходящий контейнер в C++ – set, «множество». И у меня теперь будет не словарь, не отображение какое-то непонятное, а просто множество известных людей, famous_persons. Чтобы добавить во множество строчки, я должен использовать метод insert. Я пишу famous_persons.insert("Stroustrup"), и, конечно же, от Денниса Ритчи. famous_persons. insert("Ritchie"). Никаких «= true», я просто добавил элементы в множество. Теперь я могу вывести элементы этого множества. [БЕЗ СЛОВ] Напишу некоторую функцию PrintSet. Что я увижу? Во-первых, я увижу, что перебрать элементы множества можно точно так же, как и перебрать элементы вектора, – с помощью цикла for: for (auto x : s), вывести х. И здесь у меня выведется мое множество. Давайте я попробую скомпилировать код, увижу, что он не компилируется, потому что компилятор не знает типа set, значит, мне нужно подключить библиотеку set. Так и сделаем. Снова скомпилируем. Запустим код и увидим, что у меня теперь во множестве есть элементы: Ritchie и Stroustrup. Во-первых, видно, что множество не сохраняет порядок. И действительно, с математической точки зрения, множество ничего не обещает про порядок элементов. В данном случае в C++ гарантируется, что элементы множества хранятся в отсортированном порядке, но все-таки не в том порядке, в котором я их вставлял. Это первое. Второе: у меня гарантируется уникальность элементов. Если я почему-то, вдруг, случайно или намеренно добавлю Страуструпа в этот замечательный словарь и распечатаю, простите, не словарь, а множество, и распечатаю это множество, то я увижу, что у него все еще два элемента: Ritchie и Stroustrup. То есть, контейнер set в C++ за нас проверяет уникальность элементов, хранит только уникальные элементы. Более того, поскольку, как я говорил, все контейнеры в C++ в чем-то похожи, у set также есть метод size, и я могу его вызвать, если хочу вывести размер этого множества. Давайте увидим, что размер множества равен 2. Действительно, он равен 2, несмотря на то, что я добавил Страуструпа два раза. Давайте я все-таки не буду его добавлять второй раз. Но продемонстрирую еще один метод. Если я хочу удалить кого-то из множества известных людей. Например, давайте я добавлю туда кого-нибудь неизвестного, например, себя. Распечатаю это множество, затем опомнюсь и тут же себя оттуда удалю. Удаление из множества происходит с помощью метода, который у нас вспоминается из рассказа про словарь, – метод erase. Я указываю, какой элемент оттуда удалить и снова печатаю это множество. [БЕЗ СЛОВ] Я немного опечатался в названии переменной. Исправляюсь. Код скомпилировался и сейчас я ожидаю увидеть, что сначала множество имело размер 3, а затем стало иметь размер 2. Это я и вижу: сначала был размер 3, в нем были соответствующие элементы, а затем – размер 2. erase действительно сработал.