[БЕЗ СЛОВ] Итак,
мы рассмотрели словари, которые позволяют хранить пары «ключ, значение».
Давайте рассмотрим такой пример: мы захотим сохранить для каждого человека,
является ли он известным.
Наверное, в этом случае я заведу словарь, у которого ключами будут строки,
а значениями – признаки, является ли человек известным, то есть 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 действительно сработал.