BDKR_hashz字符串(自己的理解)

来源:互联网 发布:linux sd卡自动挂载 编辑:程序博客网 时间:2024/06/05 18:52

参考博客:http://www.cnblogs.com/zyf0163/p/4806951.html


hash字符串的种类很多,但是原理都差不多,这里对于BDKR_hash介绍,听着挺高大上,懂了也就那么回事。

平时我们判断一个子符串str是否是另一个字符串s的子串,我们需要一位位的比较,相对比较麻烦,但是如果我们能够把第一个字符串化为一个代表,这里用st1·,来表示, 这样我们在比较的时候,就可以每次从s的串中取出与str相同长度的子串是s1, 然后通过与str1相同的转换规则,化为一个代表s11,直接比较s11和str是否相等就可以了,这样比较的效率非常高,这就是hash字符串解决的问题。对于其中的如何转换,转换规则,以及如何比较是非常重要的。

Hash[i] = Hash[i - 1] * x + s[i](其中1 < i <= n,Hash[0] = 0)。

 对于上面的式子,不难得知,对于第k位置的字符来说,hash[k]其实就是从字符串开始位置到k的前缀和(可以这样理解,这样在后面的时候能够更好的利用)。

对于BDKR_hash来说,对于每个字符都有一个固定的编码,如上面的式子hash[i]  = hash[i - 1] * x + (s[i] - ‘a’)

暗含的是对a的编码为0, b的编码为1,c的编码为3.........。

编码的方式是自己定的。当然也可以是hash[i]  = hash[i - 1] * x + (s[i] - ‘a’+ k)    k>=0 ,那么在比较的时候,也要按照同一套规则。

对于每个字符的编码方式已经解决了,但是对于上面的式子里还有一个x。这个在解释了如何能够根据hash判断字符串相等之后,再进行讨论。

一般地,

 

而对于l - r区间的hash值,则为:

我们可以列举几项hash项:

习惯从第一项开始算。

        hash[1] = s[1]

hash[2] = s[1] * x + s[2]

hash[3] =  s[1] * x^2 + s[2] * x  +s[3]

hash[4] = s[1]  * x ^3  + s[2]  * x ^ 2 +s[3]*x + s[4]

hash[5] = s[1] * x ^ 4  + s[2] * x ^ 3 + s[3]  * x ^ 2 + s[4] * x +s[5] 

hash[6] = s[1] * x ^ 5  + s[2] * x ^ 4 + s[3] * x ^ 3 + s[4]  + x ^ 2 + s[5]  * x  + s[6]


hash(4, 6) = hash[6] - hash[4] * x^(6-4+1) = hash[6] - hash[4] * x^3 

= s[4] * x^2 + s[5] * x + s[6]

通过这个式子我们可以看出hash(4, 6)是只包含字符串第4到第6位置的字符,其他位置不涉及,这就为我们比较字符串提供了依据,也消除了其他位置字符的干扰。

还有hash(4, 6)后面的x的次幂的大小,实际上是(4,6)之间的长度-1。

接下来我们来推导一般性的式子。


hash(l, r) = s[l] * x ^(r-l) + s[l+1] * x ^ (r-l-1) +s[l+2]* x ^(r-l-2) + s[l+3] * x^(r-l-3) ................+ s[r]

当字符串str通过相同的规则转换:假设str的长度为len(这里假设字符串从下标1开始)

str[len]=  str[1] * x ^(len-1) + str[2] * x ^ (len-2) +str[3]* x ^(len-3) + str[4] * x^(len-4) ................+ str[len]

如果r-l+1= len,说明s的长度为len的子串与等长度的字符串str,有可能相等。

究竟该满足什么条件呢?对于长度相等来说r-l = len - 1,所以对于上面的两个式子x的次幂是相同的,如果两个式子要相等,除非对应位置都相等,

s[l] = str[1],    s[l+1] = str[2]...............................................

所以只要比较hash(l, r) 是否等于str[len]就可以了。这样就实现了以一个整数,来代替整个字符串一位位的比较。

也就是说,当出现等长度的r-l = len 的时候, 只要hash(l, r) == str[len]的时候,也就是说字符串s中包含str。

同时这样一定就能满足条件吗?

假设‘a’ = 0, b = 1........ ; x =  3;


比如abc = 0 * 3^2 + 1 * 3  + 2 = 5

aae = 0 * 3 ^ 2 + 0 * 3 + 5 = 5

但是abc != aae

这里出现的问题,就是上面说的x的问题。

理论上选任意x都可以,但是会发生冲突,让两个原来不相等的子串,判断为相等,x的不确定性,引出了BDKR_hash有三种处理方式:

这里给出ppt,可以自己去看看。



原创粉丝点击