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++中使用哈希函数找到两个数组的交集?

c# - EF Core 3.1 如何在多对多关系中自动映射

node.js - 将密码哈希脚本从 GO 转换为 Nodejs

c - 开放寻址冲突解决

c# - C# 中字符串的 SHA256 哈希值与网站上的哈希值不一致

hash - Go, midstate SHA-256 哈希

java - Hashtable<ArrayList<String>,boolean> 的 .contains() 方法比 ArrayList<ArrayList<String>> 快多少?

c# - 将列表框绑定(bind)到 ObservableCollection<T> 不工作 WPF

c# - 从 C# 访问托管 C++ 结构

c# - 我如何在 boo 中使用扩展方法