veo que set_intersection()
et al. del encabezado algorithm
no funcionará, ya que requieren explícitamente que se ordenen sus entradas, supongo que ya las descartó.
Se me ocurre que el enfoque "ingenuo" de iterar a través de hash A y buscar cada elemento en hash B realmente debería proporcionarle un rendimiento casi óptimo, ya que las búsquedas sucesivas en hash B irán al mismo hash. (suponiendo que ambos hashes están usando la misma función hash). Eso debería darte una localidad de memoria decente, aunque estos cubos casi con seguridad se implementan como listas vinculadas.
Aquí hay algo de código para unordered_set_difference()
, puede modificarlo para hacer las versiones para unión de conjuntos y establecer la diferencia:
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;
}
Asumiendo que tiene dos unordered_set
s, x
y y
, puede poner su intersección en z
usando:
unordered_set_intersection(
x.begin(), x.end(),
y.begin(), y.end(),
inserter(z, z.begin())
);
a diferencia bdonlan's answer, esto va a funcionar para cualquier tipo de clave, y cualquier combinación de c ontainer tipos (aunque el uso de set_intersection()
será, por supuesto, más rápido si los contenedores de origen están ordenados).
NOTA: Si las ocupaciones de cubetas son altas, es probable que sea más rápido copiar cada hash en un vector
, ordenarlas y set_intersection()
allí, ya que la búsqueda dentro de un depósito que contiene n elementos es O (n).
+1 Excelente respuesta. Sería interesante comparar este código.En realidad, podría ser más rápido (si los conjuntos son más grandes pero no demasiado grandes) para copiarlos en un conjunto ordenado y ejecutar std :: set_intersection(). – paxos1977
Gracias ceretullis. Sí, sospecho que sería más rápido si los cubos tienen una alta ocupación, aunque en ese caso sospecho que copiarlos en vectores y ordenarlos será aún más rápido, solo porque hay menos sobrecarga de memoria y no se requiere perseguir punteros. (Ordenar un vector y crear un conjunto ordenado son ambos O (nlog n).) –
Estoy un poco preocupado. ¿Estamos seguros de que std :: find funcionará bien con los iteradores en 'set'? ¿El hallazgo no se repetirá simplemente a través de cada elemento en el segundo conjunto, mientras que nosotros queremos que use el hash para el bucle? ¿No debería la función simplemente tomar una referencia al objeto set y luego usar el método '.count'? –