hash
(卑微至极...现在才会hash可真是可笑)
一、引入
哈希算法是通过一个哈希函数H,将一种数据(包括字符串、较大的数等)转化为能够用变量表示或是直接就可作为数组下标的数
通过哈希函数转化得到的数值为哈希值
通过哈希值可以实现快速查找和匹配
哈希算法主要有两种具体应用:字符串哈希 和 哈希表
二、字符串hash
1.概况
主要解决以下问题:
字符串匹配问题:寻找长度为n的主串S中的匹配串T(长度为m)出现的位置或次数的问题
做法:
通过比较长度为m的主串s的自串的哈希值y与T的哈希值是否相同
将字符串转化为可以用变量表示的数据
注:大多数字符串hash问题可以用KMP求解,但如果是从主串中每次选出两个子串判断是否匹配的问题,还是要用字符串hash求解
2.具体流程
滚动哈希:选取两个合适的互质常熟b和h(b<h),假设字符串C=c1c2...cm,
那么我们定义哈希函数:H(C) = (c1bm-1+c2bm-2+...+cmb0)mod h
正常的数字是十进制的,这里b是基数,相当于吧字符串看作是b进制数
这一过程是地推计算的
设H(C,k)为前k个字符构成的字符串的哈希值,则
H(C,k) = H(C,k - 1) * b + ck
如果判断主串的k+1的位置开始的长度为n的子串
H(C') = H(C , k + n) - H(C , k) * bn
于是只要先预处理bn,就能在O(1)时间内得到任意字符串的子串的韩细致
那么上述字符串匹配问题的算法时间复杂度就为O(n + m)
在实际算法中,可以利用32位或64位无符号整数计算哈希值,并取h = 232或h = 264,
通过自然溢出省去求模运算
3.字符串的hash的正确性
可以用双哈希降低出现相同哈希值的概率,即去不同的模数
如:h = 1e9 + 7 和 h = 1e9 + 9 (一对孪生质数)