Я вижу, что 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's answer, это действительно будет работать для любых типов ключей, а также любое сочетание с типы контейнеров (хотя использование set_intersection()
, конечно, будет быстрее, если исходные контейнеры будут отсортированы).
ПРИМЕЧАНИЕ. Если заполнение ковша высокое, скорее всего, скопировать каждый хэш в vector
, сортировать их и set_intersection()
их там, так как поиск в ведре, содержащем n элементов, равен O (n).
+1 Отличный ответ. Было бы интересно сравнить этот код.На самом деле это может быть быстрее (если наборы больше, но не слишком большие), чтобы скопировать их в отсортированный набор и запустить std :: set_intersection(). – paxos1977
Спасибо ceretullis. Да, я подозреваю, что это было бы быстрее, если бы ведра имели высокую занятость, хотя в этом случае я подозреваю, что они копируют их в векторы, и сортировка их будет еще быстрее, только потому, что нагрузка меньше памяти и не задействована в использовании указателя. (Сортировка вектора и создание сортированного набора - это O (nlog n).) –
Я немного обеспокоен. Мы уверены, что std :: find будет хорошо работать с итераторами в 'set'? Разве поиск не будет просто проходить через каждый элемент во втором наборе, тогда как мы хотим, чтобы он использовал хэш для петли? Должна ли функция просто ссылаться на заданный объект, а затем использовать метод '.count'? –