-1

我正在使用 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;
    ...
}

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

4

3 回答 3

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;
于 2014-11-20T02:48:58.777 回答
1

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

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

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

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

于 2014-11-20T02:42:15.170 回答
0

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

于 2014-11-20T03:01:09.947 回答