实现x、y、z坐标的operator<操作符

4

我有一个类型,基本上就是一个

struct { int x,y,z; } 

我希望将其作为stl映射表的密钥。由于它是自定义类型,因此需要实现operator<运算符使map进行比较操作。

我一直在努力编写能够实现这一点的函数。到目前为止,我尝试过:

return X < v.X && Y < v.Y && Z < v.Z;

这个根本不起作用,而且

return X*X+Y*Y+Z*Z < v.X*v.X+v.Y*v.Y+v.Z*v.Z;

这将会产生一个非正方形的形状:

enter image description here

请注意,x、y或z值可能为负数,这进一步使后面的解决方案无效。

有人有实现这种功能的想法吗?


这取决于您想使用的顺序... 根据您的观点,(0,-1,+1) 是否比 (1,0,-1) 大? 有许多比较二个三维点的方法,您需要指定您想使用哪种方式... - GL770
return X < v.X || Y < v.Y || Z < v.Z; 怎么样? - Gabe
你的结构体中的“小于”是什么意思?在这里,排序很重要。如果你只需要生成一个键,那么你基本上需要一些针对 x、y 和 z 的哈希函数来在比较器中使用。 - Joe
@Gabe,你不能这样做。操作符不能有歧义。 - Joe
@Joe:在这种情况下,“小于”这个意义是无关紧要的,因为OP只是试图定义一个完全排序。哈希的问题在于他可能会得到哈希冲突,然后他又回到了起点。 - Gabe
显示剩余2条评论
3个回答

11

我假设你只想要任何稳定的顺序,那么一个有序容器就可以使用。

if ( X != v.X ) return X < v.X;
if ( Y != v.Y ) return Y < v.Y;
return Z < v.Z; 

这是做什么的:如果X不相等,则按照X排序,如果相等,则按照Y排序,以此类推。


1
也被称为词典序排序。 - Lukas Schmelzeisen

7

在不同领域工作的人中,如果操作符的语义不自然,则不需要实现operator<以避免混淆。其他人可能会对less有不同的解释,使用提供的operator<比较两个点,并且会因为结果而感到困惑。

最好为您的特定映射提供比较运算符:

struct compareXYZ : std::binary_function<Point,Point,bool> {
   bool operator()( Point const & l, Point const & r ) const {
      return l.x < r.x 
          || (l.x == r.x) && (l.y < r.y)
          || (l.x == r.x) && (l.y == r.y) && l.z < r.z;
   }
};
std::map< Point, Value, compareXYZ> theMap;     // uses XYZ comparison

这样做对于地图的用户来说,点在容器中的排序方式(例如线性迭代)将会变得清晰明了,并且缺少operator<比产生一个随机结果更加不出人意料。


1
返回 l.x < r.x || l.y < r.y || l.z < r.z; 并没有实现严格弱序;也就是说,如果在 std::map<> 中实际使用此代码,将会导致未定义行为。 - ildjarn

1
一个三维向量可以通过向量的长度进行比较。
SquareRoot(X*X + Y*Y + Z*Z);

这允许负方向。


2
但如果X是负数,它将是相同的值。-2 * -2 == 2 * 2 - FrankBro
1
将它们立方和立方根。 - jmucchiello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接