Hash 如果我们事先知道密钥和分布,有没有办法创建快速哈希函数?

Hash 如果我们事先知道密钥和分布,有没有办法创建快速哈希函数?,hash,Hash,假设我们提前知道密钥和分布,并且我们想要构建快速查找字典。我们插入项目,从不删除项目 例如,这里有频率键 xyz 1000 abc 5 阿布德20 好的散列只是将xyz映射到1个bucket,将abc,abd映射到bucket 2的第一个字符的函数。xyz主导分布,因此我们将重点放在这一点上。只看1个字符比看全部3个字符快。此外,在查找过程中,一个存储桶中的元素数为1,这样我们就可以确定正在查找的密钥必须在该存储桶中。无需将xyz与xyz进行比较 因为我们事先知道密钥、分布,所以我们可以使用

假设我们提前知道密钥和分布,并且我们想要构建快速查找字典。我们插入项目,从不删除项目

例如,这里有频率键

  • xyz 1000
  • abc 5
  • 阿布德20
好的散列只是将xyz映射到1个bucket,将abc,abd映射到bucket 2的第一个字符的函数。xyz主导分布,因此我们将重点放在这一点上。只看1个字符比看全部3个字符快。此外,在查找过程中,一个存储桶中的元素数为1,这样我们就可以确定正在查找的密钥必须在该存储桶中。无需将xyz与xyz进行比较

因为我们事先知道密钥、分布,所以我们可以使用完美的散列,但是散列函数可能会很慢


我不是在寻找最佳的解决方案,而是实用的解决方案。

一些考虑因素,然后我将提出我的解决方案:

  • 如果您实现一个查找表,您需要实现两件事:一个
    哈希函数
    和一个
    冲突解决技术

  • 快速散列函数但效率低下通常会导致冲突解决缓慢:。在您的情况下,了解发行版将有所帮助,我将在下文中写道

你可以在一个桶里放上“xyz”和另外100个以“x”开头的键,但没有很好的分布。GET的最坏情况可能是O(100)或通常是O(d),其中d是铲斗的大小,这可能远离O(1)

我的解决方案考虑了分布。不是哈希函数,而是冲突技术

如果您考虑使用链接(散列到相同值的键保存在一个列表中=您提到的bucket),您可以基于如下分布实现列表:

  • 默认情况下,避免在列表的开头插入,并在O(1)中插入INSERT,在O(d)中插入GET,d-存储桶的大小
  • 但是,对于具有高分布的键,按O(d)中分布的降序插入,并且已经接近O(1)。因为高分布的钥匙将保持在第一个位置
这样:

  • 您将有非常快速的GET操作(如果您的GET操作比INSERT操作更频繁=>这对您来说是一个非常好的选择)
  • 您可以使用一个快速而简单的散列函数,正如您提出的仅基于第一个字符的散列函数一样

在您提出的简单散列函数中,不知道分布情况。因此,使用xyz的存储桶中只能有1个项目,但在此存储桶中也可以有100个项目。因此,我们必须考虑一个同时考虑键和分布的函数……如果只有三个值,线性搜索(按
xyz,abd abc
的顺序)可能会比其他任何搜索都快。@wildplasser我想他只是举了一个例子。我考虑过尝试不同的位和计算冲突。例如,假设所有键都少于10个字符。因此,我们为10个字符选择3个随机位。对随机的3位字符串进行XOR运算,然后看看这是如何实现的。对不同的3个字符重复此操作,然后重试。继续这样做1000次,然后选择最佳功能。3是任意的,它将取决于不同键的数量。是的,这是一种这样做的方法-在测试函数中的不同值后尝试选择函数。我也在考虑使用bits,因为你的问题让我想起了Hufmann编码,但我找不到更符合逻辑的解决方案。我想了很久,我想一个超级快速的散列函数不会为我买很多东西。主要是因为我正在读取密钥,因为它们是从文件中读取的。因此,我必须遍历键字符串的长度。我认为如你所说,集中精力减少碰撞是最好的。如你所说的解决碰撞的技术。