剔除list中相同的结构体数据,有三个思路:
1、两层循环,逐个比较
2、使用set容器来剔除
3、使用unique方法去重
// deduplication.cpp : 定义控制台应用程序的入口点。
//
#include <list>
#include <set>
#include <iostream>
#include <algorithm>
#include <vector>
#include <tchar.h>
using namespace std;
struct tagRecentGameItem
{
std::wstring strGameCode;
std::wstring strServerID;
__int64 nTime;
tagRecentGameItem()
: strGameCode(L"")
, strServerID(L"")
, nTime(0)
{
}
bool operator < (const tagRecentGameItem& right) const
{
if (this->nTime > right.nTime)
{
return true;
}
if (this->nTime == right.nTime)
{
//compare函数在>时返回1,<时返回-1,==时返回0
return this->strGameCode.compare(right.strGameCode) < 0;
}
return false;
}
bool operator == (const tagRecentGameItem& right) const
{
bool bEqual = false;
//_tcsicmp不区分大小写,wcscmp区分大小写
bEqual = ( 0 == _tcsicmp(this->strGameCode.c_str(), right.strGameCode.c_str()) );
bEqual &= ( 0 == _tcsicmp(this->strServerID.c_str(), right.strServerID.c_str()) );
return bEqual;
}
};
//
typedef std::list<tagRecentGameItem> listRecentGame;
typedef std::set<tagRecentGameItem> setRecentGame;
//
listRecentGame m_LocalList;
listRecentGame m_RemoteList;
setRecentGame m_setGames;
//打印结果
void print_result(listRecentGame& items)
{
listRecentGame::iterator iter = items.begin();
for (iter; iter!=items.end(); ++iter)
{
printf("gameCode: %ls\n", iter->strGameCode.c_str());
}
printf("\n");
}
//逐个比较
void deduplication1(listRecentGame& items)
{
printf("method :deduplication1\n");
items.sort();//需要重载操作符<
listRecentGame::iterator itrB = items.begin();
listRecentGame::iterator itrE = items.end();
listRecentGame::iterator itr;
for (itrB; itrB != itrE; ++itrB)
{
itr = itrB;
++itr;
for(itr; itr != itrE;)
{
if (*itr == *itrB)
{
items.erase(itr++);
}
else
{
++itr;
}
}
}
//打印结果
print_result(items);
}
//利用set容器特性去重
void deduplication2(listRecentGame& items)
{
printf("method :deduplication2\n");
listRecentGame::iterator iter1 = items.begin();
listRecentGame::iterator iter2 = items.end();
for (iter1; iter1 != iter2; ++iter1)
{
//需要重载操作符<
m_setGames.insert(*iter1);
}
//再写回list
items.clear();
setRecentGame::iterator pos = m_setGames.begin();
for (pos; pos!=m_setGames.end(); ++pos)
{
items.push_back(*pos);
}
//打印结果
print_result(items);
}
//stl的unique方法去重
void deduplication3(listRecentGame& items)
{
printf("method :deduplication3\n");
//unique函数功能是去除相邻的重复元素,注意是相邻,所以必须先使用sort函数。
items.sort();
//unique必须重载==操作符
listRecentGame::iterator new_end = unique(items.begin(), items.end());
items.erase(new_end, items.end());
//打印结果
print_result(items);
}
//
int _tmain(int argc, _TCHAR* argv[])
{
//装载本地记录
tagRecentGameItem item;
memset(&item, 0, sizeof(item));
item.strGameCode = L"abc";
item.strServerID = L"s31";
item.nTime = 20160501183417;
m_LocalList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"bcd";
item.strServerID = L"s32";
item.nTime = 20160501183418;
m_LocalList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"cde";
item.strServerID = L"s33";
item.nTime = 20160501183419;
m_LocalList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"def";
item.strServerID = L"s34";
item.nTime = 20160501183420;
m_RemoteList.push_back(item);
//装载远程记录
memset(&item, 0, sizeof(item));
item.strGameCode = L"abc";
item.strServerID = L"s31";
item.nTime = 20160501183417;
m_RemoteList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"bcd";
item.strServerID = L"s32";
item.nTime = 20160501183418;
m_RemoteList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"cde";
item.strServerID = L"s33";
item.nTime = 20160501183419;
m_RemoteList.push_back(item);
memset(&item, 0, sizeof(item));
item.strGameCode = L"def0";
item.strServerID = L"s34";
item.nTime = 20160501183420;
m_RemoteList.push_back(item);
//合并到一个list
m_LocalList.insert(m_LocalList.begin(), m_RemoteList.begin(), m_RemoteList.end());
deduplication1(m_LocalList);
deduplication2(m_LocalList);
deduplication3(m_LocalList);
system("pause");
return 0;
}
运行结果:
需要注意的地方:
STL中的排序都是默认使用小于号来排序。因此,在对结构体排序时,我们就需要重载小于号!比如:set容器在执行insert操作时,必须重载操作符<。另外,unique函数功能是去除相邻的重复元素,而在执行unique操作时必须重载操作符==。