Чтобы операция была более эффективной, функция вставки контейнера std::map
Как это делается
В этом примере мы вставим несколько элементов в контейнер std::map
1. Мы преобразуем строки в числа, поэтому включим заголовочные файлы для std::map
std::string
:#include
#include
#include
2. Далее создаем ассоциативный массив, в котором содержатся некие символы:
int main()
{
std::map
3. Теперь вставим несколько элементов и для каждого из них используем подсказку для вставки. Поскольку изначально ее у нас нет, выполним первую операцию вставки, указывая на конечный итератор ассоциативного массива:
auto insert_it (std::end(m));
4. Вставим элементы в порядке, обратном алфавитному, используя имеющуюся у нас подсказку для вставки, а затем повторно инициализируем ее значением, которое возвращает функция insert. Следующий элемент будет вставлен прямо
for (const auto &s : {"z", "y", "x", "w"}) {
insert_it = m.insert(insert_it, {s, 1});
}
5. Чтобы продемонстрировать, как
end
: m.insert(std::end(m), {"a", 1});
6. Наконец, просто выведем на экран полученный результат.
for (const auto & [key, value] : m) {
std::cout << "\"" << key << "\": " << value << ", ";
}
std::cout << '\n';
}
7. Скомпилировав и запустив программу, мы получим следующий результат. Очевидно, ошибочная подсказка при вставке ничего не испортила, поскольку порядок ассоциативного массива все еще правильный:
"a": 1, "b": 1, "c": 2, "d": 3, "w": 1, "x": 1, "y": 1, "z": 1,
Как это работает
Единственное отличие от обычной вставки в этом примере заключается в том, что мы используем дополнительный итератор-подсказку. Кроме того, мы говорили о
insert
откатится к неоптимизированной версии, которая выполнится за время Во время первой вставки у нас есть итератор, указывающий на конечный элемент ассоциативного массива, поскольку у нас нет более удачной стартовой позиции. После вставки в дерево символа z
y
, и это вполне сгодится на роль правильной подсказки. То же применимо и к символу x
, если мы будем вставлять его в дерево после добавления символа y
, и т.д. Именно поэтому вы можете использовать итератор, который был возвращен
Дополнительная информация
Что интересно, неправильная подсказка не нарушает порядок элементов в ассоциативном массиве. Как же тогда это вообще работает и что же означает выражение «амортизированное время вставки равно
Контейнер std::map