重载运算符集

时间:2014-11-20 02:36:40

标签: c++ stl stdset

我使用std :: set来实现特定的算法。该集合中有重复,因此我假设我不得不重载运算符。重载看起来像这样。

class Vec3f {
    ...

    bool operator () ( const Vector3f& v0, const Vector3f& v1 ) const {
    float epsilon = 1e-7;
    return ((v1[0] - v0[0]) > epsilon) &&  ((v1[1] - v0[1]) > epsilon) && ((v1[2] - v0[2]) > epsilon);
}       ...


"Vec3f.h"

int main(){
    ...
    std::set<Vec3f,Vec3f> visited;
    ...
}

我重载了所以我可以使用&lt; std :: set中需要运算符。如果v0&lt;该函数返回true。 v1到一定的余地。它删除了重复项,但它也删除了集合中的有效值。我知道我的套装应该有12个Vec3fs。有了重复项,它有24个Vec3fs。使用我的比较功能,它只有3个Vec3f。我考虑过使用绝对差异,但这违反了严格的弱排序标准。我的问题是:如何编写比较函数以删除重复项并仅保留唯一项?

3 个答案:

答案 0 :(得分:2)

现在,v0中的每个组件都需要小于v1中的每个组件。这不是一个严格的弱序。您应该一次检查一个组件。如果您当前检查的组件相同,则仅检查后续组件。此外,你应该放弃epsilon。虽然这对于检查浮点计算结果的等效性很有用,但它对于排序没有用,因为它也违反了严格的弱排序。最简单的方法是将operator<用于std::tuple

return std::tie(v0[0], v0[1], v0[2]) < std::tie(v1[0], v1[1], v1[2]);

否则,如果你想手动实现这个,就像这样:

if (v0[0] < v1[0]) return true;
if (v0[0] > v1[0]) return false;
if (v0[1] < v1[1]) return true;
if (v0[1] > v1[1]) return false;
if (v0[2] < v1[2]) return true;
if (v0[2] > v1[2]) return false;
return false;

答案 1 :(得分:1)

使用std::abs来比较与epsilon的差异,例如

if(std::abs(v1[0]-v0[1]) > epsilon && ...){...} // not zero

否则您可能会得到负面结果 它将始终小于您的epsilon,并且规范测试将失败。

PS:一般来说,尝试命令向量是一个坏主意,因为没有直观的数学演练,你可能会遇到很多奇怪和违反直觉的情况。

答案 2 :(得分:0)

您提到您只想使用集合,而不一定是需要排序的集合的实现。您可以考虑使用std::unordered_set,它不要求您定义排序,只需要哈希/相等函数。