有序字符串到整数哈希函数保留其参数的字典顺序
Ordered string to integer hash function preserving lexicographic order of its argument
假设我们有一个字节串集合,像往常一样按字典顺序排序。我们想定义一个散列函数,将字符串映射到整数,散列值的排序可以充分保留字符串的顺序。也就是说,给定字符串 A 小于或等于字符串 B,H(A) 应该总是产生一个小于或等于 H(B) 的值。
显然,这种不太好的散列函数是可能的。例如,我们可以为每个字符串取一个固定的前缀(比如 8 个字节),并假装它是一个 big-endian unsigned int64。结果整数将按所需顺序排序。这种方法甚至适用于较短的字符串:我们可以将一些 0 附加到一个短字符串以使其至少有前缀字节长(但前提是我们可以假设 0 不是有效的字节值)。
不幸的是,这个潜在的解决方案虽然快速且简单,但有很大的缺点。在字符串往往具有相当大的公共前缀的情况下,它变得相当无用。当“0x00”是一个有意义的字节并且我们希望将较短的字符串排在较长的字符串之前时,它无法处理比所选前缀短的字符串。
所以问题是是否可以做得更好?一些算术(或者更确切地说是 Knuth 的“具体数学”之类的)技巧可以考虑字符串的所有字节并产生适当排序的哈希值?
你能做的最好的事情是应用一个 order-preserving arithmetic encoding,基于你能想出的最好的字符串统计模型,然后取一个前缀来形成“哈希”代码。
根据该统计模型,每个哈希码的可能性都相同。
如果您的模型只是所有字符串的可能性均等,那么这将简化为您的“只需要一个前缀的想法”...所以这是否对您有用实际上取决于您对您的字符串了解多少字符串以及您需要这段代码有多好。
另请注意,许多现实模型也将允许更简单的编码方案。 “只取一个前缀”也是一个例子。
人们可能认为他们想用像这样的“哈希码”来做的大多数事情都不切实际——您最终可能会做其他事情。也许您想问问您真正的问题,我们可以通过其他方式帮助您解决。
假设我们有一个字节串集合,像往常一样按字典顺序排序。我们想定义一个散列函数,将字符串映射到整数,散列值的排序可以充分保留字符串的顺序。也就是说,给定字符串 A 小于或等于字符串 B,H(A) 应该总是产生一个小于或等于 H(B) 的值。
显然,这种不太好的散列函数是可能的。例如,我们可以为每个字符串取一个固定的前缀(比如 8 个字节),并假装它是一个 big-endian unsigned int64。结果整数将按所需顺序排序。这种方法甚至适用于较短的字符串:我们可以将一些 0 附加到一个短字符串以使其至少有前缀字节长(但前提是我们可以假设 0 不是有效的字节值)。
不幸的是,这个潜在的解决方案虽然快速且简单,但有很大的缺点。在字符串往往具有相当大的公共前缀的情况下,它变得相当无用。当“0x00”是一个有意义的字节并且我们希望将较短的字符串排在较长的字符串之前时,它无法处理比所选前缀短的字符串。
所以问题是是否可以做得更好?一些算术(或者更确切地说是 Knuth 的“具体数学”之类的)技巧可以考虑字符串的所有字节并产生适当排序的哈希值?
你能做的最好的事情是应用一个 order-preserving arithmetic encoding,基于你能想出的最好的字符串统计模型,然后取一个前缀来形成“哈希”代码。
根据该统计模型,每个哈希码的可能性都相同。
如果您的模型只是所有字符串的可能性均等,那么这将简化为您的“只需要一个前缀的想法”...所以这是否对您有用实际上取决于您对您的字符串了解多少字符串以及您需要这段代码有多好。
另请注意,许多现实模型也将允许更简单的编码方案。 “只取一个前缀”也是一个例子。
人们可能认为他们想用像这样的“哈希码”来做的大多数事情都不切实际——您最终可能会做其他事情。也许您想问问您真正的问题,我们可以通过其他方式帮助您解决。