C++ 用于插入std::无序_集合的三维整数坐标的唯一键
我有一个三维整数坐标流,对应于体素,因此在网格上对齐。我想弄清楚当前处理的三元组是否已经存在,以便过滤重复项。我能够用C++ 用于插入std::无序_集合的三维整数坐标的唯一键,c++,hash,set,unordered-set,C++,Hash,Set,Unordered Set,我有一个三维整数坐标流,对应于体素,因此在网格上对齐。我想弄清楚当前处理的三元组是否已经存在,以便过滤重复项。我能够用std::set为我的问题构建一个简单的解决方案。将xyz设为3int,registry设为std::set。我做了一个函数,返回一个像这样的bool std::array<int, 3> key = {x, y, z}; return registry.insert(key).second; std::数组键={x,y,z}; 返回注册表。插入(键)。第二; 但
std::set
为我的问题构建一个简单的解决方案。将x
y
z
设为3int
,registry
设为std::set
。我做了一个函数,返回一个像这样的bool
std::array<int, 3> key = {x, y, z};
return registry.insert(key).second;
std::数组键={x,y,z};
返回注册表。插入(键)。第二;
但就计算时间而言,这远未得到优化。阅读文档和其他主题,我知道无序集
应该更合适。事实上,这里没有必要对任何东西进行分类。此外,我猜想使用数组
作为键在插入
时进行比较是无效的
无序集
需要哈希函数。通过研究hash函数,我找到了boost::hash\u combine
以及其他选项
在我的情况下,如何有效地使用
无序集
?关键是要尽可能快。我不需要访问值,也不需要进行任何特殊计算。哇哦,不要用向量来处理这样的事情。它动态地分配。您正在消除程序的缓存潜力
只有三个int
s,所以只需创建一个包含三个int
s的struct
。或者传递一个std::array
然后再测量一次,看看会发生什么。你可能会发现这一套现在很好。如果没有,那么您可以为三个int
s创建一个散列。不过,不要费心去尝试一个总是提供唯一值的散列函数,因为这实际上违背了散列函数的目的
如果这仍然太慢,那么你可能想考虑为此提出一个合适的算法,因为集合和unOrdEdSub集合仍然会动态地分配节点。这只是一个间接层次,而不是现在的两个层次,但是零总比没有好。
我回答我自己的问题。我最初的问题格式不正确,但感谢@Damien,我理解了散列是如何被用于std::unordered.*
的。我使用了boost
#include <boost/functional/hash.hpp>
我获得了大约33%的计算时间。实际上,一个
数组
是有意义的。我的错。然而,我用数组对其进行了基准测试,发现增益为0。你为什么告诉我不要麻烦用唯一的钥匙?如果我没有一个唯一的键,我将有冲突,因此是一个坏的过滤器。你的int
的范围是多少?请注意,如回答中所述,如果没有那么多,哈希共谋就不是问题。如果是这样的问题,哈希表将永远不会被使用。。。共谋会使过程稍微慢一点,但结果是正确的,这就是问题所在。我事先不知道边界框。否则,使用向量并为每个体素指定一个ID,问题就会简化。我理解为什么很少的冲突对存储(例如哈希密码)来说不是问题,但在我的情况下,我不理解为什么它不是问题。我不理解为什么您认为存在问题。在存储Int数组时,哈希密码是一种加速查找给定数组位置或查找未存储数组的过程的方法。重复的密码会使过程变慢,没什么,明白了!这不是我的理解。在我看来,如果两个三元组共享不同的位置,但相同的散列只能插入一个,而另一个则错误地与第一个错误地混淆。但实际上,散列只是一个帮助来查找三元组,然后在发生冲突的情况下比较实际值。这很有道理,你明白了。您可以检查性能是否得到改善,如果是,则可以编辑您的问题。答案中指出了散列是合适的。如果你表现好,你可以接受。
typedef std::array<I32,3> Array;
std::unordered_set<Array, boost::hash<Array> >