std::唯一并从对象容器中删除重复项
std::unique and removing duplicates from a container of objects
我想知道是否有一种有效的方法可以根据对象的成员字段的值从容器中删除对象。 例如,我可以使用 stl::unique 和字符串列表执行以下操作:
#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;
}
打印 1001, 81...
有没有办法用下面的代码做类似的事情,或者我是否需要使用运算符"手动"执行比较并遍历容器。我想不出一个更优雅的解决方案,并且想知道这是否可以在不编写大量代码的情况下实现。任何帮助将不胜感激!
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;
}
谢谢
可以使用
std::unique
的两个选项:
定义
Packet
的operator==
方法,并将vector<Packet*>
更改为vector<Packet>
。bool Packet::operator==(const Packet& rhs) const { if (getFilingTime() != rhs.getFilingTime()) return false; if (getSpid() != rhs.getSpid()) return false; return true; } //etc. int main() { vector<Packet> pkts; pkts.push_back(Packet("10:20", "1004")); pkts.push_back(Packet("10:20", "1004")); // not unique (duplicate of the line above) pkts.push_back(Packet("10:20", "251")); pkts.push_back(Packet("10:20", "1006")); // remove packet from vector if time and ID are the same pkts.erase(unique(pkts.begin(), pkts.end()), pkts.end()); return 0; }
将向量保留为
vector<Packet*>
并定义一个方法来比较元素。bool comparePacketPtrs(Packet* lhs, Packet* rhs) { if (lhs->getFilingTime() != rhs->getFilingTime()) return false; if (lhs->getSpid() != rhs->getSpid()) return false; return true; } //etc. 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 pkts.erase(unique(pkts.begin(), pkts.end(), comparePacketPtrs), pkts.end()); return 0; }
作为unique
的替代方法,您可以简单地将元素插入set
(或C++11中的unordered_set
)。
无论您决定采用哪种方式,都需要为Packet
定义比较运算符。对于unique
,您需要operator==
;对于set
,您需要operator<
.为了完整起见,您应该定义两者及其对应项:
class Packet {
…
bool operator==(const Packet& p) const {
return fillingTime == p.fillingTime && recordID == p.recordID;
}
bool operator<(const Packet& p) const {
return fillingTime < p.fillingTime ||
(fillingTime == p.fillingTime && recordID < p.recordID);
}
bool operator!=(const Packet& p) const { return !(*this == p); }
bool operator> (const Packet& p) const { return p < *this; }
bool operator>=(const Packet& p) const { return !(*this < p); }
bool operator<=(const Packet& p) const { return !(p < *this); }
…
};
如果你使用 C++11 的 unordered_set
,你需要更进一步,定义一个哈希函数。
编辑:我刚刚注意到您正在存储指向Packet
的指针。为什么?只需直接存储Packet
即可。
相关文章:
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 如何在C++中为增加但记住删除先前对象的对象分配唯一标识符
- 从数组中删除非唯一值、保持顺序和不使用向量的最佳方法?
- 唯一/共享 ptr 用于在数组超出范围后自动删除阵列
- 将唯一值转移到左侧,并在字符串中删除重复的值
- 在迭代过程中删除向量的唯一元素?
- 当链表是列表中唯一的节点时,删除链表的头部.单联
- 从数组中删除唯一元素的最有效方法
- std::没有等价关系的唯一示例(删除连续空格)
- 从 BST 中删除唯一的节点
- 从数组中获取唯一编号,完全删除重复项
- std::唯一并从对象容器中删除重复项
- 试图引用已删除函数的唯一指针
- 如何在列表中删除重复项并只保留唯一指针
- 带有自定义删除程序错误的 c++ 唯一指针
- 使用外部定义的自定义删除程序在头文件中定义唯一指针
- 类成员唯一指针,具有初始值设定项列表外部的自定义删除程序
- 在C++中,是否允许删除列表<Pointer>::唯一
- std::唯一指针和自定义lambda删除器错误
- 从字符串中删除两个字符以获得唯一字符的可能性