- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Контейнеры map и unordered_map предоставляют оператор индексирования и соответствующую функцию at() (см. раздел 9.3.2), представленные в табл. 11.6. Типы контейнеров set не поддерживают индексацию, поскольку в наборе нет никакого "значения", связанного с ключом. Элементы сами являются ключами, поэтому операция "доступа к значению, связанному с ключом", бессмысленна. Нельзя индексировать контейнер multimap или unordered_multimap, поскольку с заданным ключом может быть ассоциировано несколько значений.
Таблица 11.6. Операторы индексирования контейнеров map и unordered_map
c[k] Возвращает элемент с ключом k; если ключа k нет в контейнере с, добавляется новый элемент, инициализированный значением с ключом k c.at(k) Проверяет наличие элемента с ключом k; если его нет в контейнере с, передает исключение out_of_range (см. раздел 5.6)Подобно другим использованным ранее операторам индексирования, оператор индексирования карт получает индекс (т.е. ключ) и возвращает связанное с ним значение. Однако, в отличие от других операторов индексирования, если такого ключа еще нет, создается новый элемент и добавляется в карту для того ключа. Ассоциированное значение инициализируется значением по умолчанию (см. раздел 3.3.1).
Рассмотрим следующий код:
map <string, size_t> word_count; // пустая карта
// вставить инициализированный значением по умолчанию элемент
// с ключом Anna; а затем установить для него значение 1
word_count["Anna"] = 1;
Ниже приведена имеющая место последовательность действий.
• В контейнере word_count происходит поиск элемента с ключом Anna. Элемент не найден.
• В контейнер word_count добавляется новая пара ключ-значение. Ключ (константная строка) содержит текст Anna. Значение инициализируется по умолчанию, в данном случае нулем.
• Вновь созданному элементу присваивается значение 1.
Поскольку оператор индексирования способен вставить элемент, его можно использовать только для карты, которая не является константной.
Индексация карт существенно отличается от индексации массивов или векторов: использование отсутствующего ключа приводит к добавлению элемента с таким ключом в карту.
Использование значения, возвращенного оператором индексированияИной способ индексирования карт, отличающий его от других использованных ранее операторов индексирования, влияет на тип возвращаемого значения. Обычно тип, возвращенный в результате обращения к значению итератора, и тип, возвращенный оператором индексирования, совпадают. У карт все не так: при индексировании возвращается объект типа mapped_type, а при обращении к значению итератора карты — объект типа value_type (см. раздел 11.3).
Общим у всех операторов индексирования является то, что они возвращают l-значение (см. раздел 4.1.1). Поскольку возвращается l-значение, возможно чтение и запись в элемент:
cout << word_count["Anna"]; // получить элемент по индексу Anna;
// выводит 1
++word_count["Anna"]; // получить элемент и добавить к нему 1
cout << word_count["Anna"]; // получить элемент и вывести его;
// выводит 2
В отличие от вектора или строки, тип данных, возвращаемых оператором индексирования карты, отличается из типа, полученного при обращении к значению итератора карты.
Тот факт, что индексирование добавляет элемент, если карта его еще не содержит, позволяет создавать удивительно сжатый код, такой как цикл в программе подсчета слов (см. раздел 11.1). С другой стороны, иногда необходимо только узнать, присутствует ли элемент, но не добавлять его в случае отсутствия. В таких случаях не следует использовать оператор индексирования.
Упражнения раздела 11.3.4Упражнение 11.24. Что делает следующая программа?
map<int, int> m;
m[0] = 1;
Упражнение 11.25. Сравните следующую программу с предыдущей:
vector<int> v;
v[0] = 1;
Упражнение 11.26. Какой тип применяется при индексировании карты? Какой тип возвращает оператор индексирования? Приведите конкретный пример, т.е. создайте карту, используйте типы, которые применимы для ее индексирования, а затем выявите типы, которые будет возвращать оператор индексирования.
11.3.5. Доступ к элементам
Ассоциативные контейнеры предоставляют различные способы поиска заданных элементов, описанные в табл. 11.7. Используемый способ зависит от решаемой задачи. Если нужно лишь выяснить, находится ли некий элемент в контейнере, то, вероятно, лучше использовать функцию find(). Для контейнеров, способных содержать только уникальные ключи, вероятно, не имеет значения, используется ли функция find() или count(). Но для контейнеров с не уникальными ключами функция count() выполняет больше работы: если элемент присутствует, ей все еще нужно подсчитать количество элементов с тем же ключом. Если знать количество не обязательно, лучше использовать функцию find():
set<int> iset = {0,1,2,3,4,5,6,7,8,9};
iset.find(1); // возвращает итератор на элемент с ключом == 1
iset.find(11); // возвращает итератор == iset.end()
iset.count(1); // возвращает 1
iset.count(11); // возвращает 0
Таблица 11.7. Функции поиска элементов в ассоциативном контейнере
Функции lower_bound() и upper_bound() неприменимы для неупорядоченных контейнеров. Оператор индексирования и функция at() применимы только для тех контейнеров map и unordered_map, которые не являются константами. c.find(k) Возвращает итератор на (первый) элемент с ключом k или итератор после конца, если такого элемента нет в контейнере c.count(k) Возвращает количество элементов с ключом k. Для контейнеров с уникальными ключами результат всегда нуль или единица c.lower_bound(k) Возвращает итератор на первый элемент, значение ключа которого не меньше, чем k c.upper_bound(k) Возвращает итератор на первый элемент, значение ключа которого больше, чем k c.equal_range(k) Возвращает пару итераторов, обозначающих элементы с ключом k. Если такового элемента нет, значение обеих переменных-членов равно c.end() Использование функции find() вместо индексирования картДля контейнеров map и unordered_map оператор индексирования представляет простейший способ поиска значения. Но, как уже упоминалось, у оператора индексирование есть серьезный побочный эффект: если искомого ключа еще нет в карте, индексирование добавляет элемент с таким ключом. Насколько правильно такое поведение, зависит от обстоятельств. Программа подсчета слов полагалась на тот факт, что использование несуществующего ключа при индексировании приводило к вставке элемента с этим ключом и значением 0.
Иногда мы хотим знать, присутствует ли элемент с заданным ключом, не изменяя карту. Нельзя использовать оператор индексирования для определения наличия элемента, поскольку при его отсутствии оператор индексирования добавит новый элемент с таким ключом. В таких случаях следует использовать функцию find():
if (word_count.find("foobar") == word_count.end())
cout << "foobar is not in the map" << endl;
Поиск элементов в контейнерах multimap и multisetПоиск элемента в ассоциативном контейнере с уникальными ключами довольно прост — элемент либо есть в контейнере, либо нет. Для контейнеров с не уникальными ключами все несколько сложнее, так как может существовать несколько элементов с заданным ключом. Когда в контейнере multimap или multiset содержится несколько элементов с одинаковым ключом, они располагаются в контейнере рядом.
Предположим, например, что, имея карту авторов и их книг, следует вывести все книги некоего автора. Эту задачу можно решить тремя способами. Самый очевидный из них — использовать функции find() и count():

