std::unique et la suppression des doublons à partir d'un conteneur d'objets
Je voudrais savoir si il existe un moyen efficace pour supprimer des objets d'un conteneur basé sur des valeurs de champs des membres de la objets. Par exemple, je peux effectuer les opérations suivantes à l'aide de la stl::unique avec une liste de chaînes de caractères:
#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
bool stringCompare(const string & l, const string & r)
{
return (l==r);
}
int main()
{
list<string> myStrings;
myStrings.push_back("1001");
myStrings.push_back("1001");
myStrings.push_back("81");
myStrings.push_back("1001");
myStrings.push_back("81");
myStrings.sort();
myStrings.erase(unique(myStrings.begin(), myStrings.end(), stringCompare), myStrings.end());
list<string>::iterator it;
for(it = myStrings.begin(); it != myStrings.end(); ++it)
{
cout << *it << endl;
}
return 0;
}
imprime 1001, 81...
Est-il un moyen que je peux faire quelque chose de similaire avec le code suivant, ou puis-je besoin pour effectuer les comparaisons "manuellement" à l'aide des opérateurs et d'une itération dans les conteneurs. Je ne pouvais pas penser à une solution plus élégante et voudrais savoir si cela est possible sans écrire beaucoup de code. Toute aide sera très appréciée!
class Packet
{
public:
Packet(string fTime, string rID) : filingTime(fTime), recordID(rID)
string getFilingTime() {return filingTime;}
string getRecordId() {return recordID;}
private:
string filingTime;
string recordID;
};
int main()
{
vector<Packet*> pkts;
pkts.push_back(new Packet("10:20", "1004"));
pkts.push_back(new Packet("10:20", "1004")); //not unique (duplicate of the line above)
pkts.push_back(new Packet("10:20", "251"));
pkts.push_back(new Packet("10:20", "1006"));
//remove packet from vector if time and ID are the same
return 0;
}
Grâce
Packet::operator==
.C'est ce que j'ai passées d'une autre méthode (pas mon code). Je pouvais changer et les choses serait plus facile je pense... Ah, je ne l'aurais cru.
OriginalL'auteur tapatron | 2012-10-11
Vous devez vous connecter pour publier un commentaire.
Deux options pour être en mesure d'utiliser
std::
:Définir un
operator==
méthode pourPacket
et modifier levector<Packet*>
àvector<Packet>
.Garder le vecteur tel que
vector<Packet*>
et de définir une méthode pour comparer les éléments.Il s'avère qu'on ne peut pas mettre de code dans une puce. Qui le savait?
Merci pour l'ajout!
Vous pouvez.
A couru dans le même problème, et est venu avec la même solution. Cependant, dans la deuxième méthode, puisque nous avons un vecteur de créer dynamiquement des instances de Paquets (à l'aide de nouvelles), n'avons-nous pas besoin de désallouer la mémoire? Ne pkts.effacer(_; _; _;) désallouer pour nous lors de la suppression d'éléments du vecteur?
OriginalL'auteur Geoff Montee
Comme une alternative à
unique
, vous pouvez simplement insérer les éléments dans unset
(ouunordered_set
en C++11).Selon la façon dont vous décidez d'aller, vous aurez besoin de définir des opérateurs de comparaison pour
Packet
. Pourunique
, vous aurez besoinoperator==
; pourset
vous aurez besoinoperator<
. Pour être complet, vous devez définir les deux, et leurs homologues:Si vous utilisez C++11 est
unordered_set
, vous aurez besoin d'aller plus loin et de définir une fonction de hachage.EDIT: je viens de remarquer que vous êtes stocker des pointeurs vers
Packet
. Pourquoi? Juste magasinPacket
directement.OriginalL'auteur Marcelo Cantos