C++. Сборник рецептов - [92]

Шрифт
Интервал

>   << " is " << p->second << endl;

> }

>}

>map — это прекрасный способ хранить пары ключ/значение. После того как вы поймете поведение его частей, таких как >operator[] и хранение данных (в виде объектов >pair), >map предоставит простоту в использовании и высокую производительность.

Смотри также

Рецепт 6.7.

6.7. Использование хеш-контейнеров

Проблема

Требуется сохранить ключи и значения, обеспечив постоянное время доступа к элементам, и не требуется хранения элементов в упорядоченном виде.

Решение

Используйте один из связанных с хешами контейнеров — >hash_map или >hash_set. Однако помните, что они не входят в число стандартных контейнеров, определяемых стандартом С++, а представляют собой расширения, включаемые большинством реализаций стандартной библиотеки. Пример 6.8 показывает, как использовать >hash_set.

Пример 6.8. Хранение строк в hash_set

>#include

>#include

>#include


>int main() {

> hash_set hsString;

> string s = "bravo";

> hsString.insert(s);

> s = "alpha";

> hsString.insert(s);

> s = "charlie";

> hsString.insert(s);

> for (hash set::const_iterator p = hsString.begin();

>  p != hsString.end(); ++p)

>  cout << *p << endl; // заметьте, что здесь не гарантируется хранение

>                      // в упорядоченном виде

>}

Обсуждение

Контейнеры, основанные на хешах, — это популярные во всех языках структуры данных, и прискорбно, что стандарт C++ не требует их реализации. Однако если требуется использовать хеш-контейнер, то не все потеряно: высока вероятность, что используемая вами реализация стандартной библиотеки содержит >hash_map и >hash_set, но тот факт, что они не стандартизованы, означает, что их интерфейсы могут отличаться от одной реализации стандартной библиотеки к другой. Я опишу хеш-контейнеры, которые поставляются в составе реализации стандартной библиотеки STLPort.

STLPort — это свободно распространяемая переносимая реализация стандартной библиотеки, существующая уже довольно длительное время и предоставляющая хеш-контейнеры. При использовании другой библиотеки интерфейс может быть другим, но общая идея будет той же самой.

Главной особенностью хеш-контейнеров (называемых во многих книгах по ассоциативными хеш-контейнерами) является то, что они в общем случае предоставляют постоянное время поиска, вставки и удаления элементов, а в худшем случае эти операции имеют линейное время. Ценой постоянного времени выполнения этих операций является то, что в хеш-контейнере они хранятся в неупорядоченном виде, как в >map.

Посмотрите на пример 6.8. Использование хеш-контейнера (в данном случае >hash_set) довольно просто — объявите его как большинство других контейнеров и начните вставлять в него элементы.

>hash_set hsString; // hash_set строк

>string s = "bravo";

>hsString.insert(s); // Вставка копии s

Использование >hash_map аналогично, за исключением того, что требуется, как минимум, указать типы данных используемых ключей и значений. Это аналогично >map.

>hash_map

>hmStrings; // Отображение строк на строки

>string key = "key";

>string val = "val";

>hmStrings[key] = val;

Это только основы использования хеш-контейнеров. Также имеется набор параметров шаблона, которые позволяют указать используемую хеш-функцию, функцию, проверяющую ключи на эквивалентность, и объект, используемый для распределения памяти. Я опишу их немного позже.

В большинстве библиотек есть четыре хеш-контейнера, и они похожи на другие ассоциативные контейнеры стандартной библиотеки (т.е. >map и >set). Это >hash_map, >hash_multimap, >hash_set и >hash_multiset. хеш-контейнеры реализуются с помощью хеш- таблицы. Хеш-таблица — это структура данных, которая обеспечивает постоянное время доступа к элементам, используя для этого хеш-функцию перехода к месту, близкому к хранению искомого объекта, а не проход по древовидной структуре. Разница между >hash_map и >hash_set состоит в том, как данные хранятся в хеш-таблице.

Объявления контейнеров, использующих хеш-таблицу, в STLPort выглядят так.

>hash_map

> Value,                   // Тип значения,

>                          // связанного с ключом

> HashFun = hash,     // Используемая хеш-функция

> EqualKey = equal_to // Функция, используемая для

>                          // проверки равенства ключей

> Alloc = alloc>;          // Используемый распределитель памяти


>hash_set

> HashFun = hash,      // Используемая хеш-функция

> EqualKey = equal_to, // Функция, используемая для

>                           // проверки равенства ключей

> Alloc = alloc>;           // Используемый распределитель памяти

>hash_map — это хеш-таблица, которая хранит значения как объекты >pair. Это означает, что когда я буду далее описывать хеш-таблицы, «элементы» в таблице будут означать пары ключ/значение. >hash_map не хранит ключи значение по отдельности (как и map). >hash_set просто хранит ключ как значение.

Параметр шаблона >HashFun — это функция, которая превращает объекты типа >Key в значения, которые могут быть сохранены как >size_t. Более подробно это описывается ниже. Параметр шаблона


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.