我正在使用C ++ set容器来删除重复项,但是我遇到了用户定义类的问题。我将比较运算符定义如下,效果很好:
bool operator < (const TLineSegment& other) const
{
int cx1 = (int)((x1 + x2) / 2.0);
int cy1 = (int)((y1 + y2) / 2.0);
int cx2 = (int)((other.x1 + other.x2) / 2.0);
int cy2 = (int)((other.y1 + other.y2) / 2.0);
if (cx1 == cx2)
return (cy1 < cy2);
else
return (cx1 < cx2);
}
但是,下面的代码通过添加更多条件(在一定范围内没有重复)包含很少的重复项。我发现它在大多数情况下都有效,但它有时不起作用,真的很奇怪。我发现的一个案例是两个TLineSegments是相同的(但不是同一个实例),并且它们都插入了。
bool operator < (const TLineSegment& other) const
{
const int epi = 5;
int cx1 = (int)((x1 + x2) / 2.0);
int cy1 = (int)((y1 + y2) / 2.0);
int cx2 = (int)((other.x1 + other.x2) / 2.0);
int cy2 = (int)((other.y1 + other.y2) / 2.0);
if (abs(cx1 - cx2) < epi) {
if (abs(cy1 - cy2) < epi) {
return false;
}
else {
return (cy1 < cy2);
}
}
else {
return (cx1 < cx2);
}
答案 0 :(得分:0)
我们将线段(-n,0):(n,0)
与线段(-x,-y):(x,y)
进行比较。因此(cx1,cy1)
和(cx2,cy2)
都是(0,0)
。对于operator<
的两种实现,结果在任一方向上都是false
,这意味着两个线段是等效的。也就是说,以(0,0)
为中心的任何线段都等同于其他所有这样的线段?!
这显然是不正确的。
最简单的方法是利用定义operator<
的{{3}}并执行以下操作:
std::tuple<int, int, int, int> tied() const {
// can be just auto in C++14. typically I'd say use std::tie()
// but we're dealing with ints right?
return std::make_tuple(x1, y1, x2, y2);
}
bool operator < (const TLineSegment& other) const
{
return tied() < other.tied();
}