【问题标题】:How to create an efficient static hash table?如何创建高效的静态哈希表?
【发布时间】:2011-09-12 19:14:49
【问题描述】:

我需要从中创建中小型静态哈希表。通常,这些将有 5-100 个条目。创建哈希表时,所有键哈希都是预先知道的(即键已经是哈希。)目前,我创建了一个 HashMap,我对键进行排序,所以我得到 O(log n) 查找,其中 3-5平均查找我关心的尺寸。 Wikipedia 声称带有链接的简单哈希表平均会导致对完整表的 3 次查找,所以这对我来说还不值得麻烦(即,将 hash%n 作为第一个条目并进行链接。)鉴于我预先知道所有散列,似乎应该有一种简单的方法来获得快速、静态的完美散列——但我找不到一个好的指针。 IE。摊销 O(1) 访问,没有(很少?)额外开销。我应该如何实现这样的静态表?

内存使用很重要,所以我需要存储的东西越少越好。

编辑:请注意,如果我必须手动解决一次碰撞,这很好。 IE。如果我可以做一些平均具有直接访问和最坏情况3间接的链接,那很好。这并不是说我需要一个完美的哈希。

【问题讨论】:

  • 什么是适合您的完美哈希?一个没有碰撞?
  • 如果我能保证 O(1) 访问就完美了。请注意,数据已经使用不完美但相当好的散列进行散列,所以我想使用它而不是再次散列(除非我可以以很少的开销存储完美的散列。)哦,散列已经是唯一的,所以没有冲突 - 冲突只是因为我正在做哈希 -> 表索引映射而发生。
  • @Marc - 术语“完美哈希”有一个standard definition。在没有相反证据的情况下,我认为 OP 考虑到了这一点。
  • 你真的需要一个包含 5-100 个条目的哈希表吗?
  • 为了改进标准设计,您需要一些额外的数据来补偿通用哈希表所做的那些额外的少量计算。你有一些关于哈希值的具体数据吗?喜欢范围?还是你提前准备好(预编译)?

标签: hashtable data-oriented-design


【解决方案1】:

对于 c 或 c++,您可以使用 gperf

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

GNU gperf 是高度可定制的。可以选择生成 C 或 C++ 代码、发出 switch 语句或嵌套 ifs 而不是哈希表,以及调整 gperf 使用的算法。

【讨论】:

    【解决方案2】:

    在 C 中也可以使用预处理器在没有外部库的情况下使用小散列,例如:

    swich (hash_string(*p))
    {
    case HASH_S16("test"):
        ...
        break;
    case HASH_S256("An example with a long text!!!!!!!!!!!!!!!!!"):
        ...
        break;
    }
    

    看代码@http://www.heeden.nl/statichashc.htm

    【讨论】:

    • 你拼错了三明治。
    【解决方案3】:

    您可以使用Sux4j 在 Java 或 C++ 中生成最小的完美哈希。 (我不确定您使用的是 Java,但您提到了 HashMap,所以我假设。)对于 C,您可以使用 cmph 库。

    【讨论】:

      猜你喜欢
      • 2012-01-02
      • 2012-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2011-09-20
      相关资源
      最近更新 更多