我有一个问题,我想编码。我有一个生成数字0到n-1的进程,我想在生成第一个重复元素时停止它。*我正在寻找一种能够快速实现这一目标的数据结构。特别是,添加新元素并测试元素是否在结构中需要快速。预期的插入次数大约是sqrt(n)(生日问题)或实际上有点差(比如sqrt(2n))因为该过程略微偏向于唯一值。换句话说,它相当稀疏 - 使用高达十亿的数字只会使用大约30或5万个值。
哈希集或某种自平衡二叉树似乎是正确的方法,但也许有更好的方法?对于小n我认为有点阵列会更优越,但是我看着大约10 ^ 9的n,这对于我认为实用的太大了。
*实际上,它不需要立即停止 - 如果效率更高,你可以在块中生成元素并不时检查。
注意:这最初发布在math.se上,但是他们建议我转发这里。它不是研究水平,因此不适合cstheory.se。
答案 0 :(得分:2)
哈希表确实是要走的路。正确优化的整数哈希集几乎可以(不能完全忽略加载因子)作为普通数组的空间效率,同时保留您期望的高性能。使用密钥作为哈希值,不要将哈希值存储两次,保持表大小为2的幂(因此使用位掩码而不是模数)。如果您使用开放寻址并需要删除,您可以从密钥中借一点来标记墓碑。
对于50k项目,这些优化可能不值得编写自己的哈希表(尽管它本身就是一个有趣的练习!)。如果您可以使用您选择的语言中的现有哈希集,请使用它。否则,请参阅Fast and Compact Hash Tables for Integer Keys以获取各种方法的调查和基准,并考虑Robin Hood Hashing这是非常容易实现的,具有良好的最坏情况保证,虽然在上述论文中没有提及,但它是相当的我的经验很快(主要是因为它是线性探测的简单修改并继承了它的优点)。我的C实现 - 遗憾的是还不公开 - 甚至不包括250行代码,包括空格和注释,其中没有一个是棘手的(与其他哈希表相比)。这没有任何微观优化。
答案 1 :(得分:0)
我认为最好的数据结构是hashTable。最重要的部分是哈希函数,您可以创建自己的哈希函数,也可以使用MurmurHash / CityHash进行统一分发。