传递运算符==以在c++中设置

passing operator== to set in c++

本文关键字:设置 c++ 以在 运算符      更新时间:2023-10-16

我想有一个set<double> S;,并在其中插入一些双打。但我希望集合考虑1.0000001 == 1.0000000(使用epsilon比较双打)(我的意思是,如果我将两个数字都插入集合,set.size()应该等于1)。我知道如何将运算符()(用于比较)传递到集合,但我不知道如何传递函数:

const double eps = 1e-8;
bool operator==(double a, double b)
{
    return abs(a - b) < eps;
}

去片场。

p.S.:谢谢希德@Sid:我发现:运算符==没有被std::set使用。元素a和b被认为是相等的iff!(a<b)&amp!(b<a)。

简单的答案是你不能,至少不是那么容易。你必须定义一个比较运算符,该运算符定义一个严格的弱订购。如果你有类似的东西:

bool
cmpDouble( double lhs, double rhs )
{
    return abs( lhs - rhs ) < eps
        ? false
        : lhs < rhs;
}

则CCD_ 3不定义等价关系,所以一个主要要求没有得到满足。

可以使用以下内容:

bool
cmpDouble( double lhs, double rhs )
{
    double iLhs;
    modf( 1e8 * lhs, &iLhs );
    double iRhs;
    modf( 1e8 * rhs, &iRhs );
    return iLhs < iRhs;
}

但坦率地说,我怀疑如果你的替身来源需要这个在某种程度上,它们可能不适合存储在set中。

如果您有比较函数,那么为什么需要运算符==?看看下面的线索。

std::设置用户定义的类型,如何确保没有重复的

看看梅尔达德的回答。

关闭@Sid提供的链接,似乎(无论多么明智或不明智),您可以通过如下定义比较运算符来做到这一点:

const double eps = 1e-8;
bool less_than(double a, double b)
{
    return a < b - eps;
}
bool greater_than(double a, double b)
{
    return a > b + eps;
}

在将替身插入集合之前,您需要量化它们。

如果您考虑1.0000000<=范围内的所有数字x<1.00000002要相同,只需将该范围内的所有数字替换为1.0000000,然后将它们插入集合中。同样地,对于1.000002<=x<1.000004等

这种方法避免了比较运算符和传递性的所有问题。

这似乎是个坏主意。考虑数字1.00000001.00000011.0000002的情况。如果先插入1.0000001,则不允许将其他任何数字添加到集合中。如果您先添加1.00000001.0000002,则可以稍后添加另一个。

此外,set使用operator<来定义其关系,而不是相等。我看不出有什么方法可以编写一个依赖于epsilon的严格弱排序,它不会产生一个正确排序的容器。容器仅依赖于operator<或其他比较,并且无法指定相等操作。

更好的方法是只使用普通的<比较,并在构建集合后进行后处理,以清理您不再需要的元素。如果您向我们提供有关您试图解决的真实问题的更多信息,我们可能会提供帮助。

const double eps = 1e-8;
bool compare(double a, double b)
{
    return (abs(a - b) > eps) ? (a < b) : false;
}
set<int,bool(*)(double,double)> set (compare);

struct Compare
{
    bool operator()(double a, double b) const
    {
        return (abs(a - b) > eps) ? (a < b) : false;
    }
};
set<int,Compare> set;