Как реализовать std :: set или std :: hash_set для фильтрации дублированного элемента в списке массивов? - PullRequest
1 голос
/ 14 сентября 2010

Учитывая приведенный ниже сценарий, у меня есть список элемента, который может иметь некоторый дублированный элемент. Я хотел бы отфильтровать элемент, чтобы напечатать единственный уникальный элемент.

Вместо того чтобы дублировать список, удаляющий дублирующийся элемент, я попытался вставить их в std :: set и std :: hash_set. Тем не менее я не нашел полезного примера для выполнения операции.

Поэтому я надеюсь получить ваш совет по следующему коду:

#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
********/

Ответы [ 2 ]

1 голос
/ 14 сентября 2010

Возможно, я не понимаю, но если вы хотите скопировать элементы std::list в std::set, вы можете использовать std::copy с 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));
0 голосов
/ 14 сентября 2010

Удаление дубликатов легко, при условии, что вы можете изменить последовательность.

Сначала вам понадобятся функторы равенства и равенства:

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;
  }
};

Затем отсортируйте список с помощью компаратора:

swList.sort (less_SWVERSIONSTRUCT ());

А теперь удалите последовательности повторяющихся членов:

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

Готово.

...