【问题标题】:Understanding Skiena's description of "Hashing and Strings"了解 Skiena 对“哈希和字符串”的描述
【发布时间】:2015-05-19 14:08:32
【问题描述】:
在 Skiena 的“算法设计手册”一书中,以下段落出现在第 80 页的标题 3.7 散列和字符串
下
令 α 为给定字符串 S 所在的字母表的大小
书面。设 char(c) 是一个映射每个符号的函数
将字母表转换为从 0 到 α - 1 的唯一整数。
上一段中的“字母大小”是什么意思?不是所有的字母(a-z)都有相同的大小吗?还有怎么可能把字符串 S 写在字母 α 上。字母不是拼成一个字符串吗?
【问题讨论】:
标签:
algorithm
hashmap
hashtable
string-hashing
【解决方案1】:
我一直在努力理解散列函数,直到我找到了它的用法示例。 Skiena 所描述的是一种 Rabin-Karp 字符串搜索算法的变体,如 Wikipedia 所述。
使用的哈希函数如下:
让α 是给定字符串S 所在的字母表的大小
书面。让char(c) 是一个映射每个符号的函数
字母表转换为从0 到α − 1 的唯一整数:
字母的大小α是可以用来表示字符串S的符号个数。
来自上面链接的维基百科页面:
Rabin 指纹将每个子字符串视为某个基数的数字,
底通常是一个大素数。例如,如果子字符串是
"hi" 和基是 101,哈希值是:
104 * 101^1 + 105 * 101^0 = 10609 // (ASCII of 'h' is 104 and of 'i' is 105).
请注意,Skiena 将 char() 函数定义为从字母表符号到从 0 到 α − 1 的整数的映射,而在 Wikipedia 示例中,数字代码实际上可以大于字母表大小,无论如何,这应该让您了解如何应用公式。
【解决方案2】:
我认为您可能对“字母”的含义感到困惑。字母表不是单个符号,而是字符串中可能出现的所有可能符号的集合。英文字母表有 26 个符号。希伯来字母表有 22 个符号(它们与英语字母表的符号不同)。
【解决方案3】:
字母的大小 α 是指可用于字符串 S 的符号总数。根据情况,字母可能会有所不同。例如,可以使用字母表{0,1} (α=2) 来表示二进制数,可以使用拉丁文小写字母{a,...,z} (α=26) 或使用{0,...,9,A,...,F} (α=16) 来表示十六进制数的符号)。