Hacer un perfil de mi código CPU-bound me ha sugerido pasar mucho tiempo comprobando si un contenedor contiene elementos completamente únicos. Suponiendo que tengo algo de gran contenedor de elementos sin ordenar (con <
y =
definido), tengo dos ideas sobre cómo se puede hacer esto:Determinar si un vector no ordenado <T> tiene todos los elementos únicos
El primero utilizando un conjunto:
template <class T>
bool is_unique(vector<T> X) {
set<T> Y(X.begin(), X.end());
return X.size() == Y.size();
}
El segundo bucle sobre los elementos:
template <class T>
bool is_unique2(vector<T> X) {
typename vector<T>::iterator i,j;
for(i=X.begin();i!=X.end();++i) {
for(j=i+1;j!=X.end();++j) {
if(*i == *j) return 0;
}
}
return 1;
}
los he probado lo mejor que pueda, y de lo que se desprende de la lectura de la documentación sobre STL, la respuesta es (como de costumbre), depende. Creo que en el primer caso, si todos los elementos son únicos, es muy rápido, pero si hay una gran degeneración, la operación parece tomar O (N^2) tiempo. Para el enfoque de iterador anidado, lo opuesto parece ser cierto, se ilumina rápidamente si X[0]==X[1]
pero toma (comprensiblemente) O (N^2) tiempo si todos los elementos son únicos.
¿Hay una mejor manera de hacerlo, quizás un algoritmo STL creado para este propósito? Si no es así, ¿hay alguna sugerencia que permita un poco más de eficiencia?
¿Se debe permitir que el contenedor contenga duplicados? Tal vez necesitas un juego, no un vector? –
Su implementación si 'is_unique' sería más rápido si tomó como' const vector & 'como su argumento en lugar de aceptar su argumento por valor. De esta forma, evitas hacer una copia del vector y luego también copiar esa copia en un conjunto. –
@ Neil, el contenedor necesita acceso aleatorio (de ahí el vector) para otras partes del código. – Hooked