类似于下面的链接,
https://stackoverflow.com/a/30424281/1442787
我有我的课Point
带有成员变量 double x,y,z
.
我已经重载了 operator <
在我的类里面将值插入 std::map
bool Point::operator<(const Point &p)const{
return ( x < p.x
|| ( x == p.x
&& ( y < p.y
|| ( y == p.y
&& z < p.z))));
}
我已经用 Point 类作为键和 std::pair
定义了我的 map 作为值(value)
typedef std::pair<int,int> mypair;
typedef std::map<Point, mypair> mymap;
std::map
不允许插入重复键。
但是,在我的代码中,在插入键/值对时,重复的键也被插入,如下所示
map:0.436612,16.527741,0.000000,22,2 map:0.454781,17.427262,15.264347,74,12 map:0.454781,17.427262,15.264347,27,11 map:0.608370,17.373443,20.124160,21,13 map:0.608370,17.373443,20.124160,69,11
重复插入的原因可能是什么?
最佳答案
您的问题是浮点值很少比较相等,尤其是当它们是计算结果时(但在更微不足道的情况下它们可能不相等,因为它们在内存中的存储大小与在寄存器中的大小不同)。
首先,您应该避免使用 float 作为键。
如果你真的想这样做,那么你应该有一些特定于域的比较运算符。您可以使用 epsilon-tolerance(如果 abs(x - y) < e
两个 float 相等,其中 e
是一些小值),或者您可以使用随数字缩放的公差值(基本上,产生类似于“两个数字相等”的东西到一定数量的有效数字”)。单元测试库,例如 the Boost Test library使用这些类型的比较。对于点,您可以使用基于距离的相等性:如果两个点彼此之间的距离小于某个值,则它们相等。
之前我提到了相等谓词。你可以这样比较:
bool Point::operator==(const point &p)const{
// Using Manhattan distance here.
return (x - p.x) + (y - p.y) + (z - p.z) < 0.0001;
}
bool Point::operator<(const Point &p)const{
return p != *this && ( x < p.x
|| ( x == p.x
&& ( y < p.y
|| ( y == p.y
&& z < p.z))));
}
关于c++ - std::map 中的重复删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46036448/