考虑一类类型的双打
class path_cost {
double length;
double time;
};
如果我想按字典顺序排列 的列表path_costs
,我有问题。继续阅读:)
如果我像这样对相等性测试使用完全相等
bool operator<(const path_cost& rhs) const {
if (length == rhs.length) return time < rhs.time;
return length < rhs.length;
}
结果的顺序很可能是错误的,因为一个小的偏差(例如由于长度计算中的数值不准确)可能会导致长度测试失败,例如
{ 231.00000000000001, 40 } < { 231.00000000000002, 10 }
错误地持有。
如果我另外使用这样的公差
bool operator<(const path_cost& rhs) const {
if (std::fabs(length-rhs.length)<1-e6)) return time < rhs.time;
return length < rhs.length;
}
那么排序算法可能会严重失败,因为 <-operator 不再是可传递的(也就是说,如果 a < b 和 b < c 则 a < c 可能不成立)
有任何想法吗?解决方案?我考虑过对实线进行分区,以便每个分区内的数字被认为是相等的,但这仍然留下了太多相等测试失败但不应该失败的情况。
(James Curran 更新,希望能解释问题):鉴于数字:
- A = {231.0000001200, 10}
- B = {231.0000000500, 40}
C = {231.0000000100, 60}
- A.Length 和 B.Length 相差 7-e7,所以我们使用时间,并且 A < B。
- B.Length & C.Length 相差 4-e7,所以我们使用时间,并且 B < C。
- A.Length 和 C.Length 相差 1.1-e6,所以我们使用长度,并且 A > C。
(由 Esben Mose Hansen 更新)这不是纯粹的理论。当给定非传递排序运算符时,标准排序算法往往会崩溃或更糟。这正是我一直在努力解决的问题(男孩调试起来很有趣;))