Карта С++ STL: время доступа O (1)?

Ищет ли ключ std::map O(1)? Я думал, что это так, пока я не подумал об этом больше. Он основан на реализации дерева, поэтому время поиска должно быть O (log N), правильно?

И возможно ли, чтобы O (1) искал строковый ключ, возможно, std::unordered_map?


person stewart99    schedule 17.04.2013    source источник


Ответы (3)


Сложность поиска для std::map составляет O(log N) (логарифмический в размер контейнера).

Согласно параграфу 23.4.4.3/4 стандарта С++ 11 для std::map::operator []:

Сложность: логарифмическая.

Сложность поиска std::unordered_map составляет O(1) (постоянная) в в среднем случае и O(N) (линейно) в худшем случае.

Согласно параграфу 23.5.4.3/4 стандарта C++11 на std::unordered_map::operator []

Сложность: в среднем O(1), в худшем случае O(size()).

ПРИМЕЧАНИЕ:

Если ваш вопрос касается только сложности вычислений, то то, что написано выше, должно ответить на него. Вычислительная сложность операции, по сути, измеряется размером контейнера (количеством содержащихся в нем элементов).

Однако, если вы ищете способ выполнения поиска O(1) в контейнере, который использует строковые ключи и где сложность поиска постоянна относительно длины строки, а не к размеру контейнера, то ответ таков, что std::unordered_map не будет соответствовать вашим требованиям.

Чтобы найти ключ, сначала необходимо создать его хэш; когда ключ является строкой, сама эта операция может быть линейной по размеру строки. Затем реализация должна сравнить ключ со всеми строковыми ключами в одном сегменте, и каждое из этих сравнений, в свою очередь, линейно зависит от размера этих строк.

person Andy Prowl    schedule 17.04.2013
comment
unordered_map по-прежнему будет варьироваться в зависимости от размера строк, не так ли? Для каждого поиска потребуется генерация хэша и сравнение ключей для каждого элемента в корзине. - person Mark Ransom; 17.04.2013
comment
@MarkRansom: сложность обычно измеряется размером контейнера, то есть количеством содержащихся в нем элементов. Длина строк, безусловно, может повлиять на производительность, но не влияет на сложность вычислений. - person Andy Prowl; 17.04.2013
comment
Да, я знаю, что нотация O вообще этого не выражает, но, похоже, это вызывает беспокойство в вопросе. - person Mark Ransom; 17.04.2013
comment
@MarkRansom: я могу ошибаться, но мне кажется, что ОП здесь связана с вычислительной сложностью. - person Andy Prowl; 17.04.2013
comment
Я согласен с Марком в том, что вопрос о том, можно ли получить O(1) с помощью строкового ключа, может намекнуть на то, что пользователь в этом заинтересован. - person David Rodríguez - dribeas; 17.04.2013
comment
@DavidRodríguez-dribeas: Хорошо, тогда я доверяю вам, ребята. Я немного расширил свой ответ. - person Andy Prowl; 17.04.2013
comment
@MarkRansom: Кажется, вы правы в отношении опасений ОП. я расширил свой ответ - person Andy Prowl; 17.04.2013
comment
Спасибо за обновление. Я бы +1 но ты уже давно понял, так как все что ты сказал было абсолютной правдой. - person Mark Ransom; 17.04.2013
comment
@MarkRansom - Вы правы, reg. Каждый поиск потребует генерации хэша, но неправильный регистр. [Каждый поиск потребует] ключевого сравнения каждого элемента в корзине. Если последние были правильными, то сложность становится линейной. Все, что говорит O(1), это то, что он независим от количества элементов в контейнере. Насколько известно, вычисление самого хеша может занять целую вечность. - person Happy Green Kid Naps; 04.05.2013
comment
@HappyGreenKidNaps, да, хэш-таблица может стать линейной, если все хэши попадут в одно и то же ведро. Хотя обычно этого не происходит. Обратите внимание на цитату в ответе: наихудший случай O(size()). Известно, что служба подвергается атаке, специально выбирая ключи с одинаковым хэшем, если известен алгоритм хеширования. См., например. anchor.com.au/blog/2012/12/ - person Mark Ransom; 04.05.2013
comment
@MarkRansom - большая разница между желанием и возможностью (как вы сами заметили - это разница между наихудшим и средним случаем). - person Happy Green Kid Naps; 06.05.2013

Да, действительно std::map будет O(log N) и std::unordered_map будет иметь среднюю сложность с постоянным временем и O(N) в худшем случае, если будет слишком много хеш-коллизий.

person Shafik Yaghmour    schedule 17.04.2013
comment
Ожидается O(1). Довольно легко построить вырожденный случай, когда это O(N). - person doublep; 17.04.2013

В основном std::map реализован с использованием красно-черного дерева. В красно-черном дереве операция вставки и удаления занимает O(LogN) времени, поэтому в std::map временная сложность составляет O(LogN) каждого элемента.

std::unodered_map реализован с использованием хеширования, где каждая операция занимает время O(1).

person Savaliya Vivek    schedule 28.10.2018