假设我有一个N字符串列表,在编译时已知。
我想生成(在编译时)一个函数,它将每个字符串映射到1到N之间的不同整数。该函数应该花费很少的时间或空间来执行。
例如,假设我的字符串是:
{"apple", "orange", "banana"}
这样的功能可能会返回:
f("apple") -> 2
f("orange") -> 1
f("banana") -> 3
生成此功能的策略是什么?
我正在考虑在编译时分析字符串并查找一些我可以修改或添加的常量或其他常量?
编译时生成时间/空间可能非常昂贵(但显然不是那么荒谬)。
答案 0 :(得分:1)
假设你有 m 不同的字符串,并让 a i,j 成为 j 的第二个字符 i 字符串。在下文中,我将假设它们都具有相同的长度。如果j≥| a i ,将 a i,j 视为空字符,可以很容易地将其转换为任何合理的编程语言| 的
我建议的想法由两部分组成:
查找(最多) m - 1 位置区分字符串,并存储这些位置。
通过将字符串视为length- m 向量,并存储完美哈希函数的参数,创建一个完美的哈希函数。
显然,一般来说,哈希函数必须至少检查 m - 1 位置。通过归纳很容易看到这一点。对于2个字符串,必须至少检查1个字符。假设对于 i 字符串是正确的:必须检查 i - 1 位置。通过在每个 i 字符串的末尾附加0来创建一组新的字符串,并添加一个与其中一个字符串相同的新字符串,除非它在结尾处有一个1。 / p>
相反,显而易见的是,最多可以找到 m - 1 位置,足以区分字符串(对于某些集合,当然可能会更低的数量,低至log to the base of base字母大小 m )。同样,通过归纳很容易看出来。两个不同的字符串在某个位置必须不同。将字符串放在带有 m 行的矩阵中,必须有一些列不是所有字符都相同。将矩阵划分为两个或多个部分,并将参数递归地应用于具有多于2行的每个部分,显示了这一点。
假设 m - 1 位置是 p 1 ,...,p m - 1 。在下面,回忆 a i,p j 的含义 p j ≥| a i | :它是空字符。
让我们定义 h(a i )=Σ j = 1 m - 1 [q j < / sub> a i,p j %n] ,用于随机 q j 和一些名词的。那么 h 是known to be a universal hash function:对碰撞的概率 P(x≠y∧h(x)= h(y))≤1/ n 。
给定通用散列函数,有known constructions for creating a perfect hash function from it。也许最简单的是创建一个大小 m 2 的向量,然后用 n = m 2 <连续尝试上面的 h / sup> 随机系数,直到没有碰撞。在实现此目标之前所需的尝试次数预计为2,并且需要更多尝试的概率会呈指数级下降。
答案 1 :(得分:0)
很简单。制作一本字典并为第一个单词分配1,为第二个单词分配2,......不需要让事情变得复杂,只需对你的单词进行编号。
要使查找生效,请使用trie或二进制搜索或您的语言提供的任何工具。