字符串的模式匹配:RK算法
来源:互联网 发布:2g神优化单机游戏 编辑:程序博客网 时间:2024/05/16 05:30
RK算法是由Rabin和Karp共同提出的一个算法。
RK算法是对BF算法的一个改进:在BF算法中,每一个字符都需要进行比较,并且当我们发现首字符匹配时仍然需要比较剩余的所有字符。而在RK算法中,就尝试只进行一次比较来判定两者是否相等。
RK算法也可以进行多模式匹配,在论文查重等实际应用中一般都是使用此算法。
时间复杂度:O(MN)(实际应用中往往较快,期望时间为O(M+N))
RK算法的基本思想
使用HASH比较。
如果两个字符串hash后的值不相同,则它们肯定不相同;如果它们hash后的值相同,它们不一定相同。
RK算法的基本思想就是:将模式串P的hash值跟主串T中的每一个长度为|P|的子串的hash值比较。如果不同,则它们肯定不相等;如果相同,由于哈希冲突存在,也需要按照BF算法诸位比较。
RK算法的求解过程
设模式串为P,其长度为m,主串为S,其长度为n。则模式串P可以看作是一个m位的d进制数A,主串S可以看作是一个n位的d进制数。我们的模式匹配过程就是将A与主串中的每个长度为m的d进制数S[t…t+m-1] (t=0,1,2,…,n-m+1)的值做比较,所以整个模式匹配过程就变成了两个d进制数之间的比较过程。例如模式串为123,主串为65127451234,就是将十进制数123跟十进制数651, 512, 127, 274, 745, 451, 512, 123的逐个比较过程。
明确了匹配过程,下面就是求解A和求解S[t…t+m-1] (t=0,1,2,…,n-m+1)的过程:
1)求解A。根据多项式计算方法, A = P[m-1] + d * (P[m-2] + d * (P[m-3] + …+ d * (P[1] + d*P[0])…))
2)求解S[t…t+m-1]。为了方便表示,我们设S[t…t+m-1] = St,则S[t+1…t+m] = St+1
假设已求得St,现在要求St+1,需要注意的是St+1是St去掉高位数据,其余的m-1位乘以d后再在最低位加一位得到。于是
St+1 = d * (St – dm-1*S[t]) + S[t+m]
如果A的值太大,比较的过程会比较耗时,这个时候我们可以将这个大数mod q(q是一个大素数),同理,st也mod q,将两个取模之后的数相比较。
例子:
假设有字符串T:”ABCDEFG”和模式串P:”DEF”。
1、首先计算模式串P的HASH值Hd,然后按照模式串P的长度将字符串T取子串”ABC”, “BCD”, “CDE”, “DEF”计算HASH值, 分别为Ha、Hb、Hc、Hd。
2、当Hd相等时,仍然要比较一次子串“DEF”和模式串“DEF”是否一致。
3、如果子串“DEF”和模式串P“DEF”不一致。则继续取字符串T的子串“EFG”的HASH值和模式串P的HASH值比较。
RK算法的具体实现
#define q 144451#define d 26int isMatch(char *S, int i, char *P, int m){ int is, ip; for(is=i, ip=0; is != m && ip != m; is++, ip++) if(S[is] != P[ip]) return 0; return 1;}/* * 字符串匹配的RK算法 * Author:Rabin & Karp * 实现:CobbLiu * 若成功匹配返回主串中的偏移,否则返回-1 */int RK(char *S, char *P){ int m = strlen(P); int n = strlen(S); unsigned int h = 1 unsigned int A = 0; unsigned int St = 0; int i; //初始化,算出最d进制下的最高位 for(i = 0;i < m - 1;i++) h = (h*d) % q; for(i = 0; i != m; i++){ A = (d*A + (P[i] - 'a')) % q; St = (d*St + (S[i] - 'a')) % q; } for(i = 0; i != n-m; i++){ if(A == St) if(isMatch(S,i,P,m)) return i; St = (d*(St - h*(S[i]-'a'))+(S[i+m]-'a')) % q; } return -1;}
- 字符串的模式匹配:RK算法
- 字符串匹配的RK算法+随机
- 串的模式匹配算法---RK
- 串的模式匹配算法---RK
- 串的模式匹配算法---RK
- 串的模式匹配算法---RK
- 串的模式匹配算法---RK
- 串的模式匹配算法---RK
- 字符串匹配之RK算法
- LeetCode Implement strStr()(朴素的字符串匹配,RK算法,KMP算法)
- RK字符串匹配随机算法(C语言)
- 字符串匹配算法综述:BF、RK、KMP、BM、Sunday
- 【字符串RK匹配】POJ 1200
- 字符串的模式匹配算法--KMP算法
- 字符串匹配算法 -- 暴力破解法(朴素法),RK算法,KMP算法
- 字符串模式匹配算法
- 字符串模式匹配算法
- 字符串模式匹配算法
- Android NullPointerException FragmentHostCallback.getHandler()
- Cocos2d-x 2.2.3 使用NDK配置编译环境
- Java中hashCode的作用
- $.extend
- 上传,解析Excel文件并保存数据到数据库
- 字符串的模式匹配:RK算法
- 【SimpliciTI】01.将SimpliciTI-CCS-1.1.1工程导入到CCSV6
- SourceTree使用方法
- oracle insert 方法 分类
- [性能测试]性能测试基础概念
- SQL SUM() 函数
- JNI和NDK编程
- GYM 101173 A.Appearance Analysis(map)
- ”最小公倍数与最大公约数“测试代码 程序原理及测试截屏