传递运算符 == 在 c++ 中设置
我想要一个 set
并向其中插入一些双精度数。但我希望集合考虑 1.0000001 == 1.0000000
(使用 epsilon 比较双精度数)(我的意思是,如果我将两个数字插入集合中,set.size() 应等于 1)。我知道如何将 operator() (用于比较)传递给集合,但我不知道如何将 function:
const double eps = 1e-8;
bool operator==(double a, double b)
{
return abs(a - b) < eps;
}
传递给集合。
PS:感谢席德。 @Sid:我发现:std::set 不使用operator==。元素 a 和 b 被视为相等 iff !(a < b) && !(b<a)。
I want to have a set<double> S;
and insert some doubles into it. but I want the set to consider 1.0000001 == 1.0000000
(comparing doubles using epsilon) (I mean if I insert both of the numbers to the set, set.size() should equal to one). I know how to pass the operator() (for comparing) to the set but I don't know how to pass the function:
const double eps = 1e-8;
bool operator==(double a, double b)
{
return abs(a - b) < eps;
}
to the set.
P.S: Thanks to Sid. @Sid: I found out that: operator== is not used by std::set. Elements a and b are considered equal iff !(a < b) && !(b < a).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
简单的答案是你不能,至少不能那么容易。你
必须定义一个比较运算符,它定义了严格的弱
订购。如果你有类似的东西:
那么
! (a < b) && ! (b < a)
没有定义等价关系,因此不满足主要要求。
可以使用类似的东西:
但坦率地说,我怀疑如果你的双打来源需要这个
诸如此类的事情,它们可能不适合存储在
集合
中。The simple answer is that you can't, at least not that easily. You
have to define a comparison operator which defines a strict weak
ordering. If you have something like:
then
! (a < b) && ! (b < a)
doesn't define an equivalencerelationship, so a major requirement isn't met.
It's possible to use something like:
But frankly, I suspect that if the source of your doubles requires this
sort of thing, they probably aren't appropriate for storing in a
set
.如果你有比较函数那么为什么还需要operator==?看看下面的线程。
std::set 具有用户定义的类型,如何确保没有重复项
请参阅Mehrdad 的回答。
If you have the comparison function then why do you need operator== ? Take a look at the following thread.
std::set with user defined type, how to ensure no duplicates
Look at Mehrdad's answer.
离开@Sid提供的链接,似乎(无论明智或不明智),您可以通过定义比较运算符来做到这一点,如下所示:
Going off the link provided by @Sid, it seems that (however well- or ill-advised it is), you can do this by defining your comparison operators as follows:
您需要在将双打插入集合之前对其进行量化。
如果考虑 1.0000000 <= x < 范围内的所有数字1.0000002 是相同的,只需将这个范围内的所有数字替换为 1.0000000 在将其插入集合中即可。同样对于 1.0000002 <= x < 1.0000004 等。
这种方法避免了比较运算符和传递性的所有问题。
You need to quantize your doubles before inserting them into the set.
If you consider all numbers in the range 1.0000000 <= x < 1.0000002 to be identical, simply replace all numbers in this range by 1.0000000 before inserting them into the set. Likewise for 1.0000002 <= x < 1.0000004 etc.
This approach avoids all issues with comparison operators and transitivity.
这似乎是个坏主意。考虑数字
1.0000000
、1.0000001
、1.0000002
的情况。如果您首先插入1.0000001
,则其他数字都不允许添加到该集合中。如果您先添加1.0000000
或1.0000002
,则可以稍后添加另一个。此外,
set
使用operator<
来定义其关系,而不是相等。我看不到一种编写依赖于 epsilon 的严格弱排序的方法,它只是不会产生正确排序的容器。容器仅依赖于运算符<
或其他比较,并且无法指定相等运算。更好的方法是仅使用正常的
<
比较,并在构建集合后进行后处理以清理不再需要的元素。如果您向我们提供有关您试图解决的真实问题的更多信息,我们也许能够提供帮助。This seems like a bad idea. Consider the case of the numbers
1.0000000
,1.0000001
,1.0000002
. If you insert1.0000001
first then neither of the other numbers would be allowed to be added to the set. If you add1.0000000
or1.0000002
first then the other could be added later.Additionally,
set
usesoperator<
to define its relationship, NOT equality. I can't see a way of writing a strict weak ordering that relies on an epsilon, it's just not going to result in a properly sorted container. The container relies just onoperator<
or other comparison and there's no way of specifying an equality operation.Better is to just use the normal
<
comparison and do post-processing after you've built the set to clean up the elements you don't want anymore. If you give us more information about the real problem you're trying to solve we may be able to help.