C++ std::map中的重复删除

C++ std::map中的重复删除,c++,duplicates,containers,stdmap,C++,Duplicates,Containers,Stdmap,与下面的链接类似 我有我的类点,带有成员变量双x,y,z 我重载了运算符您的问题是浮点值很少作为相等值进行比较,特别是当它们是计算结果时(但在更普通的情况下它们可能是不相等的,因为它们在内存中的存储大小与在寄存器中的存储大小不同) 首先,应该避免使用浮点作为键 如果您真的想这样做,那么您应该有一些特定于域的比较运算符。您可以使用ε公差(如果abs(x-y)

与下面的链接类似

我有我的类
,带有成员变量
双x,y,z


我重载了
运算符您的问题是浮点值很少作为相等值进行比较,特别是当它们是计算结果时(但在更普通的情况下它们可能是不相等的,因为它们在内存中的存储大小与在寄存器中的存储大小不同)

首先,应该避免使用浮点作为键

如果您真的想这样做,那么您应该有一些特定于域的比较运算符。您可以使用ε公差(如果
abs(x-y)
,则两个浮点数相等,其中
e
是一些较小的值),或者您可以使用随数字缩放的公差值(基本上,产生类似“两个数字等于某个有效数字”的结果)。单元测试库,例如,使用这些类型的比较。对于点,可以使用基于距离的相等:如果两个点之间的距离小于某个值,则两个点相等

前面我提到了相等谓词。你可以这样比较:

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))));
}
bool Point::operator==(常量点&p)常量{
//在这里使用曼哈顿距离。
返回值(x-p.x)+(y-p.y)+(z-p.z)<0.0001;
}

bool Point::operator我建议您改用
std::multimap
,因为它可以存储重复的值

如果要确保要添加的给定点不在现有点的小公差范围内,那么我将检查
x
坐标在公差范围内的任何点

因此,要找到该点,可以创建一个点:

 Point search { x - tolerance, -Inf, -Inf };

然后使用
下限
作为起点,并测试任何后续点,直到其
x
坐标大于
x+公差

这将有助于查看一些代码,例如:
运算符或打赌比较双倍是否相等是问题所在
0.454781
0.454781
看起来是相等的,但它们可能不是浮点/双精度与用于打印它们的精度之比。两个双精度几乎永远不相等,请使用εtolerance@tobi303使用重载<运算符对值进行排序,不可能使用ε公差此代码并不比原始代码好,因为如果存在公差范围内的点,您可能会遇到与原始代码相同的问题,例如,您可能有一个点
a
b
公差范围内,而一个点
c
在点的公差范围内
b
但不是点
a
。因此,在这种情况下,要么在添加点之前进行舍入,然后与适当的公差(或存储缩放值)进行比较,要么确保其代码能够容忍这些情况……这就是为什么我说使用浮点作为映射键通常是个坏主意。从概念上讲,它是一个连续的值,用作键毫无意义。OP需要唯一的值,并且有(接近)重复项,而不是相反的方式。你读过我的全部答案了吗?我的第二个建议是,如果OP想要唯一的值,应该怎么做。感谢您在comparator函数中使用epsilon提供的反馈!
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
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))));
}
 Point search { x - tolerance, -Inf, -Inf };