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,可以自己去看看。
- BDKR_hashz字符串(自己的理解)
- Java的OOP思想(自己理解)
- ++i和i++ (自己的理解)
- 观察者模式(摘抄 + 自己的理解)
- 浅谈自己理解的socket(1)
- 浅谈自己理解的socket(2)
- 补码-自己的理解
- 自己理解的Fragment
- 封装自己的理解
- zookeeper自己的理解
- 自己理解的KMP
- CSRF自己的理解!!
- 自己的理解JVM
- 自己理解的GMF
- 自己理解的算法
- textcnn自己的理解
- SpringMVC自己的理解
- MyBatis自己的理解
- poj2387 Til the Cows Come Home(dijkstra)
- 数据库设计中应注意的问题
- 第十一篇:C代码调用Java代码之项目实战
- HDU 4002 数论
- springboot学习笔记五
- BDKR_hashz字符串(自己的理解)
- hdu 2680 Choose the best route【dijstra+反向建图】
- POJ
- 58面试整理
- poj3026 Borg Maze
- 杭电acm2040:亲和数(两整数真约数和互等)
- 6.递归调用 函数 (-斐波那契数列)
- 在Ubuntu 12.04 64bit搭建Android编译环境后,重启卡住在Ubuntu logo,进不了图形界面
- python爬虫之快速构造标准格式headers