【问题标题】:Minimal perfect hash function最小完美散列函数
【发布时间】:2011-07-19 06:55:38
【问题描述】:

我有很多整数在 [0; 2^63-1]。然而,只有 10^8 个整数。 没有重复。完整列表在编译时是已知的,但它只是唯一的随机数。这些数字永远不会改变
显式地存储一个整数,需要 8 个字节,并且有关联的 1 个字节值,因此显式存储需要大约 860 MB。
所以我想找到最小的完美散列函数来将 10^8 个整数中的每一个从 [0;2^63-1] 映射到 [0;10^8-1]。我应该只找到这个函数一次,数据永远不会改变,函数可能很复杂。但它应该是最小的、完美的,并且计算应该很快。我怎样才能更好地做到这一点?如果发生某些子序列,也许可以找到并使用它们?
谢谢。

【问题讨论】:

  • 编译时已知的完整列表?我的建议是自己“手动”分配数字,然后编写一个脚本以您所需的编程语言吐出地图的静态声明。如果它永远不会改变,那么使用静态数据结构来完美映射值将是您理想的解决方案。我用引号表示“手动”,因为您显然不会手动操作。有关哪些工具可以为您分配的想法,请参阅其他 cmets 和答案。

标签: perfect-hash


【解决方案1】:

让您的计算机为您完成工作:

http://www.gnu.org/software/gperf/

引用:“GNU gperf 是一个完美的散列函数生成器。对于给定的字符串列表,它会生成一个散列函数和散列表,以 C 或 C++ 代码的形式,用于根据输入字符串查找值。哈希函数是完美的,也就是说哈希表没有冲突,哈希表查找只需要单个字符串比较。”

【讨论】:

  • 但为此,CMPH 会更好,因为它旨在为非常大的键集创建最小的完美哈希函数。
  • 谢谢,我可能两个都试试。
【解决方案2】:

我正在处理an algorithm and Java implementation that needs less than 1.6 bits per key

以前,我实现了a minimal perfect hash function tool in Java,每个密钥需要少于 2.0 位。

其他算法在CMPH中实现。例如,默认情况下,CHD 每个密钥需要大约 2.06 位。它可以配置为使用更少的空间,但生成速度会更慢。

【讨论】:

  • 我正在研究一种改进的算法,每个条目需要少于 1.58 位。
  • 你有什么写的代码吗?我试图为 Long 数据类型实现它,但遇到 indexoutofbounds 错误
  • @sss999 目前文档不多;你可以阅读测试用例。也许创建一个带有测试用例和异常的issue,这样我就可以看看问题可能是什么
  • 我正在查看 LongCollection 测试用例,因为我需要长值作为输入。一旦我有了 buff ref,你能告诉我你在哪里存储输入的哈希值以及如何读取它们?
  • @sss999 不存储哈希值。我认为提出一个新问题并提供您使用过的代码和您需要什么是有意义的。然后您可以为我添加评论,以便我看到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 2010-10-19
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 2017-12-23
相关资源
最近更新 更多