std:: multimap получение двух диапазонов
Я использую C++ std::multimap
, и мне приходится перебирать два разных ключа. Есть ли эффективный способ сделать это, кроме создания двух диапазонов и циклического перебора этих диапазонов отдельно?
Вот как я делаю это сейчас:
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range;
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2;
// get the range of String key
range = multimap.equal_range(key1);
range2 = multimap.equal_range(key2);
for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it)
{
...
}
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2)
{
...
}
3 ответа:
Код, с которого вы начали, самый простой.
Если вы действительно хотите перебирать два диапазона в одном цикле, вы можете создать пользовательский итератор, который берет два диапазона итератора, перебирает первый, пока это не будет сделано, а затем переключается на второй. Это, вероятно, больше проблем, чем стоит, так как вам нужно будет реализовать все члены итератора самостоятельно.
Edit: я слишком много думал об этом; легко просто изменить два цикла в один один.
for (std::multimap<String, Object*>::iterator it = range.first; it != range2.second; ++it) { if (it == range.second) { it = range2.first; if (it == range2.second) break; } ... }
Boost делает это, конечно. Использование Boost.Диапазон и его функция
join
дадут вам то, что вы хотите. Дополнительную информацию смотрите в разделе Boost Range Library: последовательное прохождение двух диапазонов.
Если у вас есть доступ к C++-11 (Visual Studio 10+, gcc-4.5+) и Вам разрешено его использовать
auto
- это настоящая жемчужина:// get the range of String key auto range = multimap.equal_range(key1); auto range2 = multimap.equal_range(key2); for (auto it = range.first; it != range.second; ++it) { ... } for (auto it2 = range2.first; it2 != range2.second; ++it2) { ... }
В любом случае, я бы просто проверил ключи и сделал только второй цикл, если key2 != ключ1. Проверка итераторов каждый раз в цикле имеет некоторую стоимость.
Std:: set_difference первого диапазона от второго может упростить код. Может быть, std:: set_union два диапазона и вставить через back_inserter в набор, так что вы получите только одну копию?
Некоторые эксперименты могут быть в порядке. Не забудьте поставить свою первую догадку в смесь. Это может удивить вас, будучи просто прекрасным с точки зрения скорости. Если диапазоны, как правило, очень длинные и / или операция цикла не является дорогостоящей, это может не стоить головной боли дополнительной бухгалтерии.