我使用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。我考虑过使用绝对差异,但这违反了严格的弱排序标准。我的问题是:如何编写比较函数以删除重复项并仅保留唯一项?
答案 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
,并且规范测试将失败。
答案 2 :(得分:0)
您提到您只想使用集合,而不一定是需要排序的集合的实现。您可以考虑使用std::unordered_set
,它不要求您定义排序,只需要哈希/相等函数。