6.15. Контейнеры multimap и multiset
6.15. Контейнеры multimap и multiset
Контейнеры map и set не допускают повторяющихся значений ключей, а multimap (мультиотображение) и multiset (мультимножество) позволяют сохранять ключи с дублирующимися значениями. Например, в телефонном справочнике может понадобиться отдельный список номеров для каждого абонента. В перечне книг одного автора может быть несколько названий, а в нашей программе с одним словом текста сопоставляется несколько позиций. Для использования multimap и multiset нужно включить соответствующий заголовочный файл – map или set:
#include map
multimap key_type, value_type multimapName;
Для прохода по мультиотображению или мультимножеству можно воспользоваться комбинацией итератора, который возвращает find() (он указывает на первый найденный элемент), и значения, которое возвращает count(). (Это работает, поскольку в данных контейнерах элементы с одинаковыми ключами обязательно являются соседними). Например:
#include map
#include string
void code_fragment()
{
multimap string, string authors;
string search_item( "Alain de Botton" );
// ...
int number = authors.count( search_item );
mu1timap string,string ::iterator iter;
iter = authors.find( search_item );
for ( int cnt = 0; cnt number; ++cnt, ++-iter )
do_something( *iter );
// ...
}
Более элегантный способ перебрать все значения с одинаковыми ключами использует специальную функцию-член equal_range(), которая возвращает пару итераторов. Один из них указывает на первое найденное значение, а второй – на следующее за последним найденным. Если последний из найденных элементов является последним в контейнере, второй итератор содержит величину, равную end():
#include map
#include string
#include utility
void code_fragment()
{
multimap string, string authors;
// ...
string search_item( "Haruki Murakami" );
while ( cin cin search_item )
switch ( authors.count( search_item ))
{
// не найдено
case 0:
break;
// найден 1, обычный find()
case 1: {
multimap string, string : iterator iter;
iter = authors.find( search_item );
// обработка элемента ...
break;
}
// найдено несколько ...
default:
{
typedef multimapstring,string::iterator iterator;
pair iterator, iterator pos;
// pos.first - адрес 1-го найденного
// pos.second - адрес 1-го отличного
// от найденного
pos = authors.equa1_range( search_item );
for (; pos.first != pos.second; pos.first++ )
// обработка элемента ...
}
}
}
Вставка и удаление элементов в multimap и multiset ничем не отличаются от аналогичных операций с контейнерами map и set. Функция equal_range() доставляет итераторную пару, задающую диапазон удаляемых элементов:
#include multimap
#include string
typedef multimap string, string ::iterator iterator;
pair iterator, iterator pos;
string search_item( "Kazuo Ishiguro" );
// authors - multimapstring, string
// эквивалентно
// authors.erase( search_item );
pos = authors.equa1_range( search_item );
authors.erase( pos.first, pos.second );
При каждом вызове функции-члена insert() добавляется новый элемент, даже если в контейнере уже был элемент с таким же ключом. Например:
typedef multimapstring,string::value_type valType;
multimapstring,string authors;
// первый элемент с ключом Barth
authors.insert( valType (
string( "Barth, John" ),
string( "Sot-Weed Factor" )));
// второй элемент с ключом Barth
authors.insert( va1Type(
string( "Barth, John" ),
string( "Lost in the Funhouse" )));
Контейнер multimap не поддерживает операцию взятия индекса. Поэтому следующее выражение ошибочно:
authors[ "Barth, John" ]; // ошибка: multimap
Упражнение 6.28
Перепишите программу текстового поиска из раздела 6.14 с использованием multimap для хранения позиций слов. Каковы производительность и дизайн в обоих случаях? Какое решение вам больше нравится? Почему?
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Контейнеры. Встроенные контейнеры
Контейнеры. Встроенные контейнеры В самом начале данной главы мы узнали, что все рассмотренные нами атрибуты стилей можно указывать для любых элементов Web-страниц: и блочных, и встроенных. Значит, мы можем задать размер шрифта и для абзаца (блочного тега <P>), и для
Блочные контейнеры
Блочные контейнеры Как ясно из названия, блочный контейнер может хранить только блочные элементы: абзацы, заголовки, большие цитаты, теги адреса, текст фиксированного форматирования, таблицы, аудио- и видеоролики. Блочный контейнер может содержать как один блочный
Свободно позиционируемые контейнеры
Свободно позиционируемые контейнеры Давайте вернемся назад, к языкам HTML и CSS, и посмотрим, не предложат ли они нам что-либо, радикально решающее эту проблему. Так и
Контейнеры. Встроенные контейнеры
Контейнеры. Встроенные контейнеры В самом начале данной главы мы узнали, что все рассмотренные нами атрибуты стилей можно указывать для любых элементов Web-страниц: и блочных, и встроенных. Значит, мы можем задать размер шрифта и для абзаца (блочного тега <P>), и для
Блочные контейнеры
Блочные контейнеры Как ясно из названия, блочный контейнер может хранить только блочные элементы: абзацы, заголовки, большие цитаты, теги адреса, текст фиксированного форматирования, таблицы, аудио- и видеоролики. Блочный контейнер может содержать как один блочный
Свободно позиционируемые контейнеры
Свободно позиционируемые контейнеры Давайте вернемся назад, к языкам HTML и CSS, и посмотрим, не предложат ли они нам что-либо, радикально решающее эту проблему. Так и есть! Понятие свободно позиционируемого элемента Web-страницы Откроем любую из созданных нами ранее
Глава 11. Классы—контейнеры
Глава 11. Классы—контейнеры Классы—контейнеры являются обычными шаблонными классами (template classes), которые предназначены для хранения в памяти элементов заданного типа. С++ уже предлагает много контейнеров в составе стандартной библиотеки шаблонов (STL — Standard Template Library),
Ассоциативные контейнеры
Ассоциативные контейнеры Ассоциативный контейнер содержит произвольное количество элементов одинакового типа, индексируемых некоторым ключом. Qt содержит два основных класса ассоциативных контейнеров: QМар<К, T> и QHash<K, T>.QMap<K, T> — это структура данных, которая
STL: контейнеры
STL: контейнеры Если вам нужен контейнер, по умолчанию используйте vector. — Бьярн Страуструп (Bjarne Stroustrup), [Stroustrup00] §17.7 Мы знаем, что вы уже предпочитаете использовать стандартные контейнеры вместо написанных вручную. Но какой именно контейнер следует использовать? Что должно
Контейнеры
Контейнеры В STL входит немало полезных компонентов (в том числе итераторы, алгоритмы и объекты функций), однако большинство программистов С++ ставит на первое место именно контейнеры. По сравнению с массивами контейнеры обладают большей гибкостью и функциональностью. Они
Контейнеры vector и string
Контейнеры vector и string Все контейнеры STL по-своему полезны, однако большинство программистов С++ работает с vector и string чаще, чем с их собратьями, и это вполне понятно. Ведь контейнеры vector и string разрабатывались как замена массивов, а массивы настолько полезны и удобны, что
Ассоциативные контейнеры
Ассоциативные контейнеры Ассоциативные контейнеры по некоторым характеристикам схожи с последовательными контейнерами, однако между этими категориями существует ряд принципиальных различий. Так, содержимое ассоциативных контейнеров автоматически сортируется;
Совет 22. Избегайте изменения ключа «на месте» в контейнерах set и multiset
Совет 22. Избегайте изменения ключа «на месте» в контейнерах set и multiset Понять смысл этого совета нетрудно. Контейнеры set/multiset, как и все стандартные ассоциативные контейнеры, хранят свои элементы в отсортированном порядке, и правильное поведение этих контейнеров зависит
Контейнеры
Контейнеры Контейнеры - это объекты, которые содержат другие объекты. Они управляют размещением в памяти и свобождением этих объектов через конструкторы, деструкторы, операции вставки и удаления.В следующей таблице мы полагаем, что X - контейнерный класс, содержащий
Множество с дубликатами (Multiset)
Множество с дубликатами (Multiset) multiset - это ассоциативный контейнер, который поддерживает равные ключи (возможно, содержит множественные копии того же самого значения ключа) и обеспечивает быстрый поиск ключей.template ‹class Key, class Compare = less‹Key›, template ‹class U› class Allocator = allocator›class