Самый быстрый способ определить, содержится ли элемент в мультикарте?

0

Предположим, что многомагистраль <строка, строка>. Я хочу проверить, содержится ли элемент, например, пара <строка, строка> ("foo", "bar"). Конечно, я могу пойти с чем-то вроде

auto range(myMap.equal_range("foo"));
auto it = find(range.first, range.second, pair<string, string>("foo", "bar"));

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

  • 1
    Когда у вас есть диапазон (то есть все записи с одним и тем же ключом), вы должны выполнить линейный поиск, чтобы найти соответствующее значение - альтернативы нет. std::multimap использует порядок вставки для соответствующих ключей, поэтому, возможно, вы сможете организовать вставки для вставки наиболее часто используемых элементов в первую очередь (?) ...
  • 0
    мультикарты в основном являются бинарными деревьями и поэтому должны иметь некоторый порядок значений с тем же ключом. Я думал, что должен быть способ поиска прибыли по заказу, по крайней мере, если реализация обеспечивает.
Показать ещё 10 комментариев
Теги:
multimap

4 ответа

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

Если это типичный образец доступа, я бы сказал, что multimap - неправильный контейнер?

Может быть, что-то вроде следующего?

std::map<std::string, std::set<std::string>>

Хорошо, вставка и удаление сложнее, но поиск соответствует требованиям, которые у вас есть.

0

Нет никаких гарантий относительно относительного порядка элементов с эквивалентными ключами на С++ 98, поэтому в зависимости от вашей среды сборки вы ищете линейную сложность для поиска диапазона.

Вы можете использовать пользовательский multimap, создав map которая сопоставляется с set:

// std namespace removed for brevity
map< string, set<string> > myMap;

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

0

Вы хотите просто использовать find():

 multimap<T> m;
 T t;
 // ...
 multimap<T>::iterator r = m.find(t);
 if (r != m.end()) {
     // hit
 }
  • 0
    Я хочу искать значение, а не только ключ. В противном случае я мог бы также использовать поиск или подсчет.
  • 0
    @KitFisto ок, отредактировал ответ соответственно
Показать ещё 1 комментарий
-1

Мультимапы обычно реализуются как красно-черные деревья (GNU C++ делает это). Таким образом, поиск по ним через их итераторы будет O (log n).

  • 0
    Как только найден соответствующий диапазон для данного ключа, поиск является линейным, а не логарифмическим.
  • 0
    Алгоритм поиска всегда линейный. Не могли бы вы объяснить, как я мог выполнить «поиск по итератору»?
Показать ещё 1 комментарий

Ещё вопросы

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