Я вижу, что set_intersection()
и др. из заголовка algorithm
не будет работать, поскольку они явно требуют сортировки своих входных данных — думаю, вы уже исключили их.
Мне приходит в голову, что «наивный» подход к перебору хэша A и поиску каждого элемента в хэше B должен на самом деле дать вам почти оптимальную производительность, поскольку последовательные поиски в хеше B будут выполняться в одном и том же хэш-сегменте (при условии, что оба хэши используют одну и ту же хеш-функцию). Это должно дать вам достойную локальность памяти, даже несмотря на то, что эти сегменты почти наверняка реализованы в виде связанных списков.
Вот некоторый код для unordered_set_difference()
, вы можете настроить его, чтобы сделать версии для объединения наборов и различий наборов:
template <typename InIt1, typename InIt2, typename OutIt>
OutIt unordered_set_intersection(InIt1 b1, InIt1 e1, InIt2 b2, InIt2 e2, OutIt out) {
while (!(b1 == e1)) {
if (!(std::find(b2, e2, *b1) == e2)) {
*out = *b1;
++out;
}
++b1;
}
return out;
}
Предполагая, что у вас есть два unordered_set
, x
и y
, вы можете поместить их пересечение в z
, используя:
unordered_set_intersection(
x.begin(), x.end(),
y.begin(), y.end(),
inserter(z, z.begin())
);
В отличие от ответа bdonlan, это будет работать для любого ключа типов и любой комбинации типов контейнеров (хотя использование set_intersection()
, конечно, будет быстрее, если исходные контейнеры отсортированы).
ПРИМЕЧАНИЕ. Если ведра заполнены, вероятно, быстрее скопировать каждый хэш в vector
, отсортировать их и set_intersection()
там, поскольку поиск в ведре, содержащем n элементов, выполняется O(n).
person
Community
schedule
22.05.2009