将相等运算符重载配对以插入到集合中
Pair equal operator overloading for inserting into set
我正在尝试将pair<int,int>
添加到集合中。如果一对与集合中的另一对共享相同的两个值,则不应插入该对。
这是我的非工作代码:
typedef std::pair<int, int> PairInt;
template<>
bool std::operator==(const PairInt& l, const PairInt& r)
{
return (l.first == r.first && l.second == r.second) ||
(l.first == r.second && l.second == r.first);
}
int main()
{
std::set<PairInt> intSet;
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
}
此时,即使已经有一个(1,4)对,也会添加(4,1)对。该集的最终内容是:
(1 3)
(1 4)
(4 1)
我希望它是
(1 3)
(1 4)
我曾尝试在重载方法中设置断点,但始终无法达到。我做错了什么?
集合基于operator<
(一种排序/等价关系),而不是operator==
(一种相等关系)。
要做你想做的事情,请使用自定义比较器:
#include <set>
#include <utility>
#include <cassert>
typedef std::pair<int, int> PairInt;
PairInt normalize(const PairInt& p) {
return p.second < p.first ? PairInt(p.second, p.first) : p;
}
struct Comparator {
bool operator()(const PairInt& l, const PairInt& r) const {
//Compare canonical forms of l and r.
return normalize(l) < normalize(r);
}
};
int main()
{
std::set<PairInt, Comparator> intSet;
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
assert(intSet.size() == 2);
}
您需要提供一个比较函数来查看一个项目是否小于另一个项目,而不是确定它们是否相等。下面是一个完整的例子:
#include <utility>
#include <algorithm>
#include <set>
#include <iostream>
typedef std::pair<int, int> PairInt;
typedef bool Compare(const PairInt &,const PairInt &);
bool compare(const PairInt &l,const PairInt &r)
{
int lfirst = std::min(l.first,l.second);
int rfirst = std::min(r.first,r.second);
if (lfirst<rfirst) return true;
if (rfirst<lfirst) return false;
return std::max(l.first,l.second)<std::max(r.first,r.second);
}
int main()
{
typedef std::set<PairInt,Compare*> IntSet;
IntSet intSet(compare);
intSet.insert(PairInt(1,3));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(1,4));
intSet.insert(PairInt(4,1));
for (IntSet::const_iterator i=intSet.begin(); i!=intSet.end(); ++i) {
std::cerr << i->first << "," << i->second << "n";
}
}
输出:
1,3
1,4
比较应该确定第一项是否小于第二项。所以应该是这样的:
namspace std
{
template<>
bool operator < (const PairInt& l, const PairInt& r)
{
//swap only if they're unequal to avoid infinite recursion
if (l.first != l.second)
{
//swap elements, considering your special case
if (l.first == r.second && l.second == r.first)
return l < PairInt(r.second, r.first); //call again!
}
//actual comparison is done here
if ( l.first != r.first )
return l.first < r.first;
else
return l.second < r.second;
}
}
现在它给出了所需的输出:
1,3
1,4
看看在线演示。
请注意,compare函数如下:严格弱排序
相关文章:
- 如何将结构插入到集合中并打印集合的成员
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 将基元类型插入到集合中
- 如何在一对集合的向量中插入元素?vector<pair<int,set<string>>>
- 如何将值插入到 c++ boost::multiindex 集合的特定索引中,就像在 std::list 中一样
- 为什么以相同的数量插入到集合中,基于不同的方法具有不同的运行时间?
- 将地址插入到集合中,集合的大小小于预期
- 我可以在一行代码中将向量中与条件匹配的所有元素插入到集合中吗?
- 如何插入集合
- 如何在C++的集合中插入一系列元素
- 如何在集合中插入字符
- 将集合插入/读取到地图中
- 方法插入到任何stl集合中
- C - 如何将自己类型的值插入集合中
- 如何将数组插入无序集合
- 集合的复杂性::插入
- 将配对插入集合时编译错误
- 集合未插入
- 自定义比较器,将唯一元素插入到c++中的集合中
- 插入集合时出现分段错误