c# - 完美的散列函数能保证不发生冲突吗?

标签 c# hash hashtable perfect-hash

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

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

碰撞!我对散列和散列表有什么误解吗?事实证明,完美的哈希函数并不完美。

最佳答案

在这之前你一切都好

index = foo.GetHashCode() % hashtable.Length

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

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

那么为什么我们在 Dictionary 中没有冲突?实际上,我们有。如果两个对象 AB 在字典中确实有相同的散列,我们就会发生冲突。发生的情况是字典运行 A.Equals(B) 作为最终检查,以查看两个对象实际上是否相同。如果是,您将获得重复项的异常(exception)。如果他们不这样做,则它们都保存在相同的字典哈希下。

关于c# - 完美的散列函数能保证不发生冲突吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16501514/

相关文章:

c# - C# 中 where 条件下的日期比较与 oledb 数据库

c# - 如何声明这个嵌套数组/列表?

c# - 如何在 ICSharpCode.AvalonEdit.TextEditor 中更改文本颜色?

c - 将哈希表的大小调整反射(reflect)到 C 中的 main

c++ - 开发哈希算法 : RGB Color ID and String to Int

java - 匹配 Java SHA2 输出与 MySQL SHA2 输出

powershell - 组合哈希表时 PowerShell 的行为

c# - 如何使用 FluentAssertions 断言属性的默认值?

c - 5000以下整数的哈希函数?

swift - 在可哈希类中自动实现唯一 ID