【问题标题】:Does a perfect hash function guarantee no collisions?完美的散列函数能保证没有冲突吗?
【发布时间】:2013-05-11 20:40:18
【问题描述】:

我一直在阅读和学习散列和散列表,并使用了一些代码(我对此还是很陌生,所以我可能会说一些我误解的错误)。我遇到了完美哈希函数的问题。前提是我有自己的自定义类型,它以某种方式具有完美的哈希函数:

class Foo
{
    private int data;

    override int GetHashCode()
    {
        return data.GetHashCode();
    }
}

int 的哈希码是 int 本身,所以我有一个完美的哈希函数,对吧?但是当我们使用哈希函数通过简单的公式将对象映射到哈希表时:

index = foo.GetHashCode() % hashtable.Length

我们得到一个变量索引,它也取决于我们在哈希表中有多少元素。如果哈希表的大小仅为 int.MaxValue,那么我们将拥有一个完美的哈希函数。例如,假设我们有一个大小为 2 的哈希表。如果我们对数字 1 和 3 进行哈希处理,我们会得到

1 % 2 = 1
3 % 2 = 1

碰撞!我对哈希和哈希表有什么误解吗?结果证明一个完美的哈希函数并不完美。

【问题讨论】:

  • 如果你能写出完美的哈希函数,我想有一百万美元在等着你。
  • @C.Lang 一个完美的散列函数在限制可散列数据集时很容易编写。
  • @SethCarnegie:谢谢。我通过不受限制的实现来学习。根据他在朱利安的回答中的 cmets,这就是 OP 所指的。无论如何,只是另一件事让我头疼:)\

标签: c# hash hashtable perfect-hash


【解决方案1】:

到此为止,一切顺利

index = foo.GetHashCode() % hashtable.Length

您的哈希函数是完美的,但是当您计算模数时,您实际上使用的是不同的哈希函数。在这种情况下,您的哈希函数int.GetHashCode完美的,但您使用foo.GetHashCode() % hashtable.Length的数据结构不是。也就是说,一件事是您的对象的哈希值,另一件事是保存这些对象的结构所使用的哈希值。

为了使您的数据结构也完美,它的最大大小也必须是整数的数量。

那么为什么我们在Dictionary 中没有冲突呢?事实上,我们这样做。如果两个对象AB 在字典中确实具有相同的哈希值,我们就会发生冲突。发生的情况是字典运行A.Equals(B) 作为最终检查,以查看两个对象是否实际上相同。如果是,则您会因重复而获得例外。如果没有,它们都保存在同一个字典哈希下。

【讨论】:

  • 是的,我坚持了下来,但这不就是哈希表的实现方式吗?例如在 C# 中的 Dictionary。而且一个长度为int.MaxValue的数组是不是太大而不能生效,会浪费很多内存?
  • 是的,但字典确实有冲突。发生的情况是,每当发生碰撞时,字典都会检查 Equals 方法与两个碰撞对象。那是最后的检查
  • 是的,我知道他们有碰撞,我知道存在许多碰撞解决算法,但事实并非如此。那么你知道是否可以存在一个完美的哈希函数(使用模数),以便它适用于任何大小的数组。
  • 不,没有。根据定义,如果您的模数是 n
【解决方案2】:
  1. 是的! (如前所述,根据定义)

  2. 您首先从哪里获得 p.h.f? 您想要散列 固定的,即常量 不同(即没有多重集)值的集合 S 到集合 1..|S|,双射。 显然,p.h.f 取决于集合 S.

  3. 此外,从 S 中删除一个元素,然后添加另一个元素,您几乎肯定会(新元素与旧元素)发生冲突。

  4. 所以,你实际上想要“一个 p.h.f. 用于这样那样的定义/描述的集合”。 然后我们可以尝试找到一个。

【讨论】:

    【解决方案3】:

    是的,完美的哈希函数保证不会发生冲突。

    这就是它的定义!

    来自维基百科 (http://en.wikipedia.org/wiki/Perfect_hash_function)

    集合 S 的完美散列函数是将 S 中的不同元素映射到一组整数的散列函数,没有冲突。完美的散列函数与其他散列函数有许多相同的应用,但优点是不必实现冲突解决

    【讨论】:

    • 是的,但它实际上有冲突,请参阅我制作的示例。这是一个提供一对一关系的函数。问题不在于哈希函数,而在于计算索引的方式(i = hash(obj) % length
    • 那么你做的例子不是一个完美的哈希函数。但是,您的问题“完美哈希函数是否保证没有冲突?”的答案必须是“是”,因为正如我所指出的,这正是完美哈希函数的定义。
    猜你喜欢
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多