2010-09-14 10 views
1

Étant donné le scénario ci-dessous, j'ai une liste d'éléments qui pourraient avoir des éléments en double. Je souhaite filtrer l'article, afin d'imprimer le seul élément unique. Au lieu de dupliquer une liste qui supprime l'élément dupliqué, j'ai essayé de les insérer dans std :: set et std :: hash_set. Néanmoins, je n'ai trouvé aucun exemple utile pour effectuer l'opération.Comment implémenter std :: set ou std :: hash_set pour filtrer l'élément dupliqué dans une liste de tableaux?

D'où j'espère demander votre avis sur le code suivant:

#include <list> 
//--> A struct to store software name and version 
typedef struct tagSWVERStruct{ 
    TCHAR szSWName[255]; 
    TCHAR szVersion[255]; 
}SWVERSIONSTRUCT, *LPSWVERSIONSTRUCT; 

//--> A list of struct to store software name and version 
typedef std::list<SWVERSIONSTRUCT> LISTSWVERSION, *PLISTSWVERSION; 

void main() 
{ 
    LISTSWVERSION swList; 
    SWVERSIONSTRUCT svSW1, svSW2, svSW3, svSW4; 
    CString szVersion, szName; 

    //Assign value 
    _tcscpy_s(svSW1.szSWName, _T("Adapter 1")); 
    _tcscpy_s(svSW2.szSWName, _T("Adapter 2")); 
    _tcscpy_s(svSW3.szSWName, _T("Adapter 1")); 
    _tcscpy_s(svSW4.szSWName, _T("Adapter 3")); 
    _tcscpy_s(svSW1.szVersion, _T("1.0.0")); 
    _tcscpy_s(svSW2.szVersion, _T("2.0.0")); 
    _tcscpy_s(svSW3.szVersion, _T("1.0.0")); 
    _tcscpy_s(svSW4.szVersion, _T("3.0.0")); 
    swList.push_back(svSW1); 
    swList.push_back(svSW2); 
    swList.push_back(svSW3); 
    swList.push_back(svSW4); 

    //print all the item out 
    LISTSWVERSION::iterator it = swList.begin(); 
    for(; it!=swList.end(); ++it){  
    _tprintf(_T("%s version = %s\n"), (*it).szSWName, (*it).szVersion); 
    } 
} 

/******* 
Output: 
Adapter 1 version = 1.0.0 
Adapter 2 version = 2.0.0 
Adapter 1 version = 1.0.0 
Adapter 3 version = 3.0.0 

Expected Output: 
Adapter 1 version = 1.0.0 
Adapter 2 version = 2.0.0 
Adapter 3 version = 3.0.0 
********/ 
+1

eh? vous n'utilisez pas std :: set du tout –

+1

remplacez std :: list' par 'std :: set' et' push_back' par 'insert' et vous êtes prêt à partir. Voir la réponse de Dauphic. – rubenvb

+0

** hash_set **: http://www.sgi.com/tech/stl/hash_set.html/ ** set **: http://www.sgi.com/tech/stl/set.html – log0

Répondre

0

La suppression des doublons est facile, à condition de pouvoir modifier la séquence.

D'abord, vous aurez besoin foncteurs moins que et de l'égalité:

struct less_SWVERSIONSTRUCT 
{ 
    bool operator() (SWVERSIONSTRUCT const & a, SWVERSIONSTRUCT const & b) const 
    { 
    // Replace this with the appropriate less-than relation for the structure. 
    return std::memcmp (&a, &b, sizeof (a)) < 0; 
    } 
}; 

struct eq_SWVERSIONSTRUCT 
{ 
    bool operator() (SWVERSIONSTRUCT const & a, SWVERSIONSTRUCT const & b) const 
    { 
    // Replace this with the appropriate equality relation for the structure. 
    return std::memcmp (&a, &b, sizeof (a)) == 0; 
    } 
}; 

ensuite trier la liste en utilisant le comparateur:

swList.sort (less_SWVERSIONSTRUCT()); 

Et maintenant supprimer les séquences des membres en double:

swList.erase (
    std::unique (swList.begin(), swList.end(), eq_SWVERSIONSTRUCT()), 
    swList.end()); 

Terminé.

+0

Merci pour votre aide. – wengseng

+0

Il fonctionne avec le code suivant: – wengseng

+0

swList.sort (LESS_SWVERSIONSTRUCT()); \t swList.unique (EQ_SWVERSIONSTRUCT()); – wengseng

1

Je ne peux pas être compréhensifs, mais si vous voulez copier les éléments d'un std::list dans un std::set, vous pouvez utiliser un std::copy avec un inserter.

std::list<int> list; 
list.push_back(1); 
list.push_back(2); 
list.push_back(2); 
list.push_back(3); 

std::set<int> set; 
std::copy(list.begin(), list.end(), std::inserter(set)); 
+1

Ce code suppose que la liste est déjà triée, ce qui n'est pas le cas avec l'entrée fournie dans la question. – wilx

+0

Merci, j'ai négligé 'unique' nécessitant un conteneur trié. –

+0

Cela devrait être 'std :: inserter (set, set.end())' (l'itérateur n'a pas d'importance pour 'set :: insert()' correct, c'est juste un indice de performance, end() fonctionne mieux si le les données sont triées). Hélas, cela ne fonctionne pas pour hash_set parce que 'hash_set :: insert()' ne prend pas un 2ème paramètre d'itérateur où-pour-insérer. –