Вход/Регистрация
Введение в стандартную библиотеку шаблонов C++. Описание, примеры использования, учебные задачи
вернуться

Абрамян Михаил

Шрифт:

Контейнер forward_list содержит также функции-члены before_begin и cbefore_begin, которые возвращают обычный и константный итератор, указывающий на позицию, предшествующую первому элементу контейнера. Эти итераторы позволяют использовать функции insert_after, emplace_after, splice_after и erase_after для вставки новых данных в начало контейнера forward_list и удаления начальной части его элементов.

Неупорядоченные ассоциативные контейнеры unordered_set, unordered_multiset, unordered_map и unordered_multimap обеспечивают ту же функциональность, что и стандартные упорядоченные ассоциативные контейнеры set, multiset, map и multimap (см. п. 1.2.1, 1.2.2, 1.2.6), однако для поиска по ключу в них используются хеш-функции (hash functions), генерирующие хеш-коды ключей, а также функции, сравнивающие ключи на равенство. Все элементы, ключи которых возвращают одинаковый хеш-код, помещаются в одну ячейку (bucket) неупорядоченного ассоциативного контейнера (число ячеек для контейнера может либо устанавливаться по умолчанию, либо указываться в его шаблоне). При поиске элемента по ключу вначале вычисляется хеш-код ключа, определяющий ячейку, которая может содержать элемент с данным ключом. Если эта ячейка содержит несколько элементов, то элемент с нужным ключом ищется в ней обычным перебором. Высокая скорость в подобном механизме поиска обеспечивается за счет того, что для каждого ключа можно быстро определить его хеш-код, позволяющий сразу обратиться к нужной ячейке, которая, как правило, содержит небольшое число элементов.

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

Неупорядоченные ассоциативные контейнеры содержат практически все средства, имеющиеся у упорядоченных контейнеров (см. п. 1.2.2 и 1.2.6); отсутствуют лишь функции для работы с обратными итераторами, а также функции lower_bound и upper_bound (хотя функция-член equal_range имеется). Кроме того, вместо функций key_comp и value_comp у неупорядоченных контейнеров предусмотрены функции-члены hash_function (возвращает хеш-функцию), и key_eq (возвращает функцию для сравнения ключей на равенство). Разумеется, при переборе элементов неупорядоченных ассоциативных контейнеров не гарантируется, что они будут располагаться по возрастанию ключей.

Неупорядоченные контейнеры включают также следующие функции-члены для работы с ячейками:

• max_bucket_count возвращает максимальное количество ячеек, которое можно выделить для данного контейнера;

• bucket_count возвращает количество ячеек, выделенных для данного контейнера;

• bucket(key) возвращает индекс ячейки, содержащей элементы с ключом key;

• bucket_size(n) возвращает размер ячейки с указанным индексом n;

• begin(n), end(n) и cbegin(n), cend(n) возвращают итераторы для перебора всех элементов, входящих в ячейку с индексом n.

Наконец, еще одна группа функций-членов предназначена для оптимизации размещения данных в неупорядоченных контейнерах:

• load_factor возвращает среднее число элементов к ячейке (число типа float, равное size/bucket_count);

• max_load_factor позволяет определить (функция без параметров, возвращающая результат типа float) и изменить (void-функция с параметром типа float) максимальное среднее число элементов в ячейке; контейнер автоматически увеличивает количество ячеек, если значение load_factor превысит указанное максимальное значение;

• rehash(count) позволяет явно изменить количество ячеек; в результате новое значение bucket_count будет больше или равно count, а также больше size/max_load_factor;

• reserve(n) настраивает контейнер таким образом, чтобы его размер можно было увеличивать до n элементов без автоматического увеличения количества ячеек.

1.2.9. Дополнение: обратные итераторы

Получить обратный итератор r можно из обычного (прямого) итератора p явным приведением типа, например:

Имеется функция-член rbegin, которая возвращает приведенный к типу обратного итератора итератор end, и функция-член rend, возвращающая приведенный к типу обратного итератора итератор begin.

Операции инкремента и декремента прямого и обратного оператора взаимно обратны: r++ перемещает итератор в том же направлении, что и p–, а r– – в том же направлении, что и p++.

Для операции разыменования * выполняется следующее базовое соотношение: если r может быть получен из p, то *r равно *(p – 1).

Функция-член base обратного итератора возвращает прямой итератор, который можно было бы использовать для получения данного обратного итератора явным приведением типа: если r может быть получен из p, то r.base == p. Или, иначе говоря, ((reverse_iterator)p).base == p.

Примеры

В следующем примере рассматривается последовательный контейнер cont с исходными элементами 1, 2, 3, 4, 5. Итераторы p2, p3, p4, p5 связаны с элементами 2, 3, 4, 5. Обратные итераторы r2, r3, r4, r5 определены следующим образом (rev – псевдоним типа обратного итератора для cont):

Значения разыменованных итераторов для исходного контейнера:

После выполнения оператора

значения разыменованных итераторов будут следующими («*» означает, что попытка разыменования приводит к непредсказуемым результатам):

Теперь повторно инициализируем итераторы p4 и r4

и выполним операторы

В результате значения разыменованных итераторов изменятся следующим образом:

<
  • Читать дальше
  • 1
  • ...
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: