【发布时间】:2024-01-17 09:02:01
【问题描述】:
我有一组uint32 整数,其中可能有数百万个项目。其中 50-70% 是连续的,但在输入流中它们以不可预知的顺序出现。
我需要:
将此集合压缩为范围以实现节省空间的表示。已经使用普通算法实现了这一点,因为只计算一次的范围速度在这里并不重要。经过这种转换后,结果范围的数量通常在 5 000-10 000 之间,当然,其中许多是单项。
测试某个整数的成员资格,不需要有关集合中特定范围的信息。这个必须非常快——O(1)。正在考虑minimal perfect hash functions,但他们在范围方面表现不佳。 Bitsets 空间效率非常低。其他结构,如二叉树,具有 O(log n) 的复杂度,最糟糕的是,实现会产生许多条件跳转,并且处理器无法很好地预测它们,从而导致性能不佳。
有没有专门针对整数范围的数据结构或算法来解决这个任务?
【问题讨论】:
-
您能具体说明一下您需要哪些操作吗?根据我的阅读,您有一组预先存在的范围,并且您希望从中支持“哪个范围(如果有)包含给定整数?”的操作。这是正确的吗?
-
@templatetypedef:我只需要“是/否”回答“这个数字在集合中吗?”对于预先存在的集合。主要问题是如何在具有实际空间要求的 O(1) 中做到这一点。
-
另一个想法 - 您是否考虑过使用二元决策图之类的东西?我记得 Don Knuth 曾经谈到使用零抑制二进制决策图来编码大部分为零的函数(在你的情况下,你有一个从 32 位到数字是否存在的函数,而大多数时候它不是)。这将为您提供 O(1) 查找时间(因为每次查找最多需要 32 个步骤),但我不确定它的空间效率如何。
-
一个 bitset 为 512mb。这真的是空间太大了吗?不会有另一个实用的 O(1) 数据结构。
-
@Markus Kull:512MB 太大了,因为需要同时处理多个集合。
标签: algorithm data-structures integer set range