与个人比较函数集合具有相同的值
std::set with personal comparison function have identical values
我想存储Point3D
对象的std::set
,我的比较函数定义如下(按字典顺序):
bool operator<(const Point3D &Pt1, const Point3D &Pt2)
{
const double tol = 1e-5;
if(fabs(Pt1.x() - Pt2.x()) > tol)
{
return Pt1.x() < Pt2.x();
}
else if(fabs(Pt1.y() - Pt2.y()) > tol)
{
return Pt1.y() < Pt2.y();
}
else if(fabs(Pt1.z() - Pt2.z()) > tol)
{
return Pt1.z() < Pt2.z();
}
else
{
return false;
}
}
在某些情况下,set
包含相同的点,我认为问题来自比较函数,但我没有找到确切的问题。任何帮助将不胜感激!
您的容差概念没有正确地建立严格的弱排序,因为它不是可传递的。为了方便示例,假设容忍度为1
。现在考虑:
a = 1
b = 2
c = 3
这里:!(a<b)
和!(b<c)
,但a<c
。这显然违反了严格弱排序的传递性要求。
如果你想实现一个有容错的比较,但这也是一个严格的弱排序,你必须以一致的方式对每个值进行四舍五入(例如,1.5 => 2
, 0.75 => 1
, 2.3 => 2
等),然后比较四舍五入的值。
这样做似乎非常没有意义,因为double
已经这样做了,但在最大可能的精度。当你发现1.4999999... != 1.5
.
您应该按如下方式编写比较器,并放弃公差概念:
bool operator<(const Point3D &Pt1, const Point3D &Pt2)
{
//This can be replaced with a member/free function if it is used elsewhere
auto as_tie = [](Point3D const &Pt) {
//assumes the member functions return references
//to the internal `Point3D` values.
return std::tie(Pt.x(), Pt.y(), Pt.z());
};
return as_tie(Pt1) < as_tie(Pt2);
}
如果您绝对必须有一个公差,则在将值放入Point3D
后立即将其四舍五入,或者在比较之前立即将值四舍五入(取决于系统中的其他要求)。
相关文章:
- 如何在比较时更改集合元素的值(在 c++ 中)?
- 如何为集合 c++ 建立比较器
- 集合比较器的正向声明
- 使用依赖于 "this" C++ 的比较结构初始化集合
- 集合元素类中定义的集合的比较器
- 将集合与集合进行比较的最佳算法
- 自定义比较器,将唯一元素插入到c++中的集合中
- 集合<向量<int>>必须定义比较函数吗?
- 如何在定义映射/集合时实例化比较函数(函子)
- 将不可比较的对象添加到集合中
- 比较两个无序集合的相等性有多昂贵
- 生成浮点比较的集合<和>的严重差异=
- 用C++中的比较器初始化集合
- 比较集合的当前元素和下一个元素
- 更好的std::在指针集合上查找,并将取消引用的值与常量引用值进行比较
- c++ STL集合的比较函数:比较函数可以是类的成员函数吗?
- C2100非法间接比较器和集合
- 具有透明比较器和异构意义上的非唯一元素的映射或集合
- C++ 如何比较<int>从开始到最后一个元素的集合 -1
- c++ STL集合:比较对象与外部状态