Comment supprimer les doublons de std :: vector non triés tout en conservant la commande d'origine en utilisant des algorithmes?
J'ai un tableau d'entiers que j'ai besoin de supprimer les doublons tout en maintenant la commande de la première occurrence de chaque entier. Je peux voir faire comme cela, mais imaginer qu'il y est une meilleure manière qui rend l'utilisation des algorithmes de la STL mieux? L'insertion est hors de mon contrôle, je ne peux donc pas vérifier les doublons avant de l'insérer.
int unsortedRemoveDuplicates(std::vector<int> &numbers) {
std::set<int> uniqueNumbers;
std::vector<int>::iterator allItr = numbers.begin();
std::vector<int>::iterator unique = allItr;
std::vector<int>::iterator endItr = numbers.end();
for (; allItr != endItr; ++allItr) {
const bool isUnique = uniqueNumbers.insert(*allItr).second;
if (isUnique) {
*unique = *allItr;
++unique;
}
}
const int duplicates = endItr - unique;
numbers.erase(unique, endItr);
return duplicates;
}
Comment cela peut être fait en utilisant des algorithmes de la STL?
source d'informationauteur WilliamKF | 2012-08-30
Vous devez vous connecter pour publier un commentaire.
La naïf façon est d'utiliser des
std::set
comme tout le monde vous dira. C'est exagéré, et a une mauvaise localité de cache (lent).Le smart* façon est d'utiliser des
std::vector
de manière appropriée (assurez-vous de voir la note au bas):Alors vous pouvez l'utiliser comme:
*Remarque: C'est la façon intelligente dans les cas typiquesoù le nombre de doublons n'est pas trop élevé. Pour approfondir l'analyse de la performance, voir cette réponse à une question relative à la.
Sonne comme un travail pour std::copy_if. Définir un prédicat qui garde une trace des éléments qui ont déjà été traitées et retournera false si ils en ont.
Si vous n'avez pas de C++11, vous pouvez utiliser les maladroitement nommé std::remove_copy_if et inverser la logique.
C'est non testé exemple:
Puis
où un
std::ref
a été utilisé pour éviter d'éventuels problèmes avec l'algorithme interne de copier ce qui est avec un état de foncteur, bien questd::copy_if
ne place pas les exigences sur les effets secondaires du foncteur d'être appliquée.Simple et rapide, C++11: