реализация карты с ++ с хорошей производительностью

0

Я хочу сопоставить некоторые ключи с другими структурами данных, где список ключей получен из Интернета.

std::unordered_map - O (1), но в худшем случае O (N)
std::map всегда O (log N)

Есть ли другая реализация карты с наилучшим случаем O (1) и O (log N) наихудших результатов?

  • 0
    Вы также можете реализовать карту с отсортированным вектором пар ключей и значений. здесь вставка - O (N), а поиск - O (log N), но кэширование лучше, потому что в ключах не используются указатели.
Теги:
data-structures

3 ответа

1
Лучший ответ

Наилучшая и худшая производительность std::unordered_map очень сильно зависит от качества хэш-функции. Наихудшая производительность O (N) - это когда все ваши ключи сопоставляются с одним и тем же значением хэша (т.е. 100% скорости столкновения). Итак, если у вас нет чрезвычайно ужасной хеш-функции, вы действительно не получите такую худшую производительность.

Когда дело доходит до определения производительности хэш-карты, это очень связано с вероятностями и статистикой ваших данных. В принципе, у вас есть распределение ваших входных данных (ключей), которое затем отображается на распределение хэш-значений. Если вы хорошо знаете распределение входных данных, вы можете создать хорошую хеш-функцию, которая будет отображать равномерное распределение хэш-значений. Если распределение хеш-значений очень однородно, вероятность столкновений низкая, и, следовательно, размеры ваших ковшей (группы значений с одинаковым значением хэша) будут в среднем небольшими, и это приведет к очень хорошие средние показатели. Можно сказать, что средняя производительность - O (B), где B - средний размер ковшей. Чем лучше ваша хэш-функция, тем меньше вероятность столкновения, чем ниже размеры вашего ковша, тем лучше ваша средняя производительность, и на что вы должны стремиться.

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

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

3

Как вы отметили, худший случай для std::unordered_map является линейным, поэтому вместо того, чтобы запрашивать более худший случай (такой контейнер не существует - если бы это было не стандартное его использование или, по крайней мере, обеспечивало такое изменение?) пусть вместо этого рассмотрит причину худшего случая и посмотрим, можем ли мы предотвратить это.

В этом случае std::unordered_map (почти наверняка) hashmap, так что худший случай случается, когда каждый элемент, который вы вставляете хэши в значение sme, и все они цепляются в одно ведро (эффективно делая хэш-карту связанным списком).

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

  • 0
    У вас есть мнение о хэш-функции, но такой контейнер существует: en.wikipedia.org/wiki/…
0

Как насчет этого, просто предложение.

Sudo code:

my_hash = GenHash(key)

std::unordered_map<my_hash, val, Hash = my_hash> map1   <---- Hash function of unordered_map should return its key. i.e. my_hash
std::map<key, val> map2

if my_hash is in map1
    map2[key] = val
else
    val.k = key    <---- assumes key can be stored/found inside the value
    map1[my_hash] = val

Таким образом, мы можем прекратить формирование связанных списков внутри unordered_map, что вызывает O (N). В лучшем случае вы заполняете только карту1. Дайте мне знать, если код sudo не ясен.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню