Я вижу, что 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
s, 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).