Предположим, что многомагистраль <строка, строка>. Я хочу проверить, содержится ли элемент, например, пара <строка, строка> ("foo", "bar"). Конечно, я могу пойти с чем-то вроде
auto range(myMap.equal_range("foo"));
auto it = find(range.first, range.second, pair<string, string>("foo", "bar"));
но это будет означать линейный поиск в пределах диапазона. Поскольку нужно назначить мультимап, я бы предпочел извлечь выгоду из заказа и поиска с логарифмической сложностью. Это возможно?
Если это типичный образец доступа, я бы сказал, что multimap
- неправильный контейнер?
Может быть, что-то вроде следующего?
std::map<std::string, std::set<std::string>>
Хорошо, вставка и удаление сложнее, но поиск соответствует требованиям, которые у вас есть.
Нет никаких гарантий относительно относительного порядка элементов с эквивалентными ключами на С++ 98, поэтому в зависимости от вашей среды сборки вы ищете линейную сложность для поиска диапазона.
Вы можете использовать пользовательский multimap
, создав map
которая сопоставляется с set
:
// std namespace removed for brevity
map< string, set<string> > myMap;
Это может быть полезно, если вы ожидаете больших значений с теми же ключами. В противном случае ваше оригинальное решение выглядит лучше, так как итерация не такая чистая. Должна написать функцию для поиска этого контейнера.
Вы хотите просто использовать find()
:
multimap<T> m;
T t;
// ...
multimap<T>::iterator r = m.find(t);
if (r != m.end()) {
// hit
}
Мультимапы обычно реализуются как красно-черные деревья (GNU C++ делает это). Таким образом, поиск по ним через их итераторы будет O (log n).
std::multimap
использует порядок вставки для соответствующих ключей, поэтому, возможно, вы сможете организовать вставки для вставки наиболее часто используемых элементов в первую очередь (?) ...