一尘不染

用于构建和查找整数范围集的数据结构

algorithm

我有一组uint32整数,这组中可能有数百万个项目。它们中的50-70%是连续的,但在输入流中它们以不可预测的顺序出现。

我需要:

  1. 将此集合压缩到范围内以实现空间高效的表示。由于仅计算一次速度的范围在此并不重要,因此已经使用平凡的算法实现了这一点。经过这种转换后,生成的范围数通常在5000至10000之间,当然,其中许多都是单项的。

  2. 测试某些整数的成员资格,不需要有关集合中特定范围的信息。这一步必须非常快-O(1)。正在考虑最小的完美哈希函数,但它们不能很好地与范围配合使用。位集空间利用率非常低。其他结构(例如二叉树)的复杂度为O(log n),最糟糕的情况是实现会产生许多条件跳转,并且处理器无法很好地预测它们,从而导致性能下降。

是否有专门用于整数范围的数据结构或算法来解决此任务?


阅读 121

收藏
2020-07-28

共1个答案

一尘不染

关于第二个问题:

您可以在Bloom
Filters
上查找。布隆过滤器是专门为回答O(1)中的隶属关系问题而设计的,尽管响应是nomaybe((不是像yes
/ no:p那样明确)。

maybe当然,在这种情况下,您需要进一步处理才能真正回答问题(除非在您的情况下概率回答就足够了),但是即使如此,Bloom
Filter仍可以充当网守,并直接拒绝大多数查询。

另外,您可能希望将实际范围和简并范围(单个元素)保留在不同的结构中。

  • 单个元素可能最好存储在哈希表中
  • 实际范围可以存储在排序数组中

这减少了存储在排序数组中的元素的数量,从而减少了在那里执行二进制搜索的复杂性。由于您声明许多范围退化,因此我认为您只有500-1000个范围(即小一个数量级),并且log(1000)〜10

因此,我建议采取以下步骤:

  • 布隆过滤器:如果否,则停止
  • 实际范围的排序数组:如果是,请停止
  • 单个元素的哈希表

首先执行“排序数组”测试,因为从您给出的数字(数以千计的数字合并到数千个范围中)中,如果包含一个数字,则它有可能在一个范围内,而不是单个:)

最后一点:当心O(1),虽然看起来很吸引人,但您并非处于渐近状态。很少有5000-10000的范围,因为log(10000)类似于13。因此,不要通过获得常数因数如此高而实际上比O(log
N慢)的O(1)解决方案来悲观您的实现)解决方案:)

2020-07-28