kmp算法.docx
- 文档编号:3001560
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:24
- 大小:29.84KB
kmp算法.docx
《kmp算法.docx》由会员分享,可在线阅读,更多相关《kmp算法.docx(24页珍藏版)》请在冰豆网上搜索。
kmp算法
窗体顶端
窗体底端
kmp算法
kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。
KMP算法的关键是根据给定的模式串W1,m,定义一个next函数。
next函数包含了模式串本身局部匹配的信息。
目录
编辑本段kmp算法-学习介绍
一般的KMP算法
现在讨论一般情况。
假设主串:
s:
‘s
(1)s
(2)s(3)……s(n)’;模式串:
p:
‘p
(1)p
(2)p(3)…..p(m)’
把课本上的这一段看完后,继续
现在我们假设主串第i个字符与模式串的第j(j<=m)个字符‘失配’后,主串第i个字符与模式串的第k(k 此时,s(i)≠p(j),有 主串: S (1)……s(i-j+1)……s(i-1)s(i)…………. ||(相配)||≠(失配) 匹配串: P (1)...........p(j-1)p(j) 由此,我们得到关系式 ‘p (1)p (2)p(3)…..p(j-1)’=’s(i-j+1)……s(i-1)’ 由于s(i)≠p(j),接下来s(i)将与p(k)继续比较,则模式串中的前(k-1)个字符的子串必须满足下列关系式,并且不可能存在k’>k满足下列关系式: (k ‘p (1)p (2)p(3)…..p(k-1)’=’s(i-k+1)s(i-k+2)……s(i-1)’ 即: 主串: S (1)……s(i-k+1)s(i-k+2)……s(i-1)s(i)…………. ||(相配)||||? (有待比较) 匹配串: P (1)p (2)…….....p(k-1)p(k) 现在我们把前面总结的关系综合一下 有: S (1)…s(i-j+1)…s(i-k+1)s(i-k+2)……s(i-1)s(i)…… ||(相配)||||||≠(失配) P (1)……p(j-k+1)p(j-k+2)…......p(j-1)p(j) ||(相配)||||? (有待比较) P (1)p (2)……......p(k-1)p(k) 由上,我们得到关系: 'p (1)p (2)p(3)…..p(k-1)’='p(j-k+1)p(j-k+2)……p(j-1)’ 接下来看“反之,若模式串中存在满足式(4-4)。 。 。 。 。 。 。 ”这一段。 看完这一段,如果下面的看不懂就不要看了。 直接去看那个next函数的源程序。 (伪代码) K是和next有关系的,不过在最初看的时候,你不要太追究k到底是多少,至于next值是怎么求出来的,我教你怎么学会。 课本83页不是有个例子吗? 就是图4.6 你照着源程序,看着那个例子慢慢的推出它来。 看看你做的是不是和课本上正确的next值一样。 在理解上面代码的基础上,建议自己寻找一些KMP算法的练习,也可以自己写两个较为简单的字符串进行人脑模拟这种方法的练习,以加深对算法的理解。 KMP算法的优化 KMP算法是可以被进一步优化的。 我们以一个例子来说明。 譬如我们给的P字符串是“abcdaabcab”,经过KMP算法,应当得到“特征向量”如下表所示: 下标i 0 1 2 3 4 5 6 7 8 9 p(i) a b c d a a b c a b next[i] -1 0 0 0 0 1 1 2 3 1 但是,如果此时发现p(i)==p(k),那么应当将相应的next[i]的值更改为next[k]的值。 经过优化后可以得到下面的表格: 下标i 0 1 2 3 4 5 6 7 8 9 p(i) a b c d a a b c a b next[i] -1 0 0 0 0 1 1 2 3 1 优化的next[i] -1 0 0 0 -1 1 0 0 3 0 附: KMP算法查找串S中含串P的个数count #include #include #include usingnamespacestd; inlinevoidNEXT(conststring&T,vector { //按模式串生成vector,next(T.size()) next[0]=-1; for(inti=1;i intj=next[i-1]; while(T[i]! =T[j+1]&&j>=0) j=next[j];//递推计算 if(T[i]==T[j+1])next[i]=j+1; elsenext[i]=0;// } } inlinestring: : size_typeCOUNT_KMP(conststring&S, conststring&T) { //利用模式串T的next函数求T在主串S中的个数count的KMP算法 //其中T非空, vector NEXT(T,next); string: : size_typeindex,count=0; for(index=0;index intpos=0; string: : size_typeiter=index; while(pos if(S[iter]==T[pos]){ ++iter;++pos; } else{ if(pos==0)++iter; elsepos=next[pos-1]+1; } }//whileend if(pos==T.size()&&(iter-index)==T.size())++count; }//forend returncount; } intmain(intargc,char*argv[]) { stringS="abaabcacabaabcacabaabcacabaabcacabaabcac"; stringT="ab"; string: : size_typecount=COUNT_KMP(S,T); cout< system("PAUSE"); return0; } 补上个Pascal的KMP算法源码 PROGRAMImpl_KMP; USES CRT; CONST MAX_STRLEN=255; VAR next: array[1..MAX_STRLEN]ofinteger; str_s,str_t: string; int_i: integer; Procedureget_nexst(t: string); Var j,k: integer; Begin j: =1;k: =0; whilej begin if(k=0)or(t[j]=t[k])then begin j: =j+1;k: =k+1; next[j]: =k; end elsek: =next[k]; end; End; Functionindex(s: string;t: string): integer; Var i,j: integer; Begin get_next(t); index: =0; i: =1;j: =1; while(i<=Length(s))and(j<=Length(t))do begin if(j=0)or(s[i]=t[j])then begin i: =i+1;j: =j+1; end elsej: =next[j]; ifj>Length(t)thenindex: =i-Length(t); end; End; BEGIN ClrScr;{清屏,可不要} Write(‘s=’); Readln(str_s); Write(‘t=’); Readln(str_t); int_i: =index(str_s,str_t); ifint_i<>0then begin Writeln('Found',str_t,'in',str_s,'at',int_i,'.'); end else Writeln('Cannotfind',str_t,'in',str_s,'.'); END. index函数用于模式匹配,t是模式串,s是原串。 返回模式串的位置,找不到则返回0 编辑本段基本思想 假设在模式匹配的进程中,执行T[i]和W[j]的匹配检查。 若T[i]=W[j],则继续检查T[i+1]和W[j+1]是否匹配。 若T[i]<>W[j],则分成两种情况: 若j=1,则模式串右移一位,检查T[i+1]和W[1]是否匹配;若1 重复此过程直到j=m或i=n结束。 文献中,朱洪对KMP算法作了修改,他修改了KMP算法中的next函数,即求next函数时不但要求W[1,next(j)-1]=W[j-(next(j)-1),j-1],而且要求W[next(j)]<>W[j],他记修改后的next函数为newnext。 显然在模式串字符重复高的情况下,朱洪的KMP算法比KMP算法更加有效。 以下给出朱洪的改进KMP算法和next函数和newnext函数的计算算法。 算法1.1: KMP串匹配算法 输入: 正文串j和模式串W[1,m] 输出: 匹配结果match[1,n] procedureKMP begin i=1 j=1 whilei<=ndo whilej<>0andW[j]<>T[i]do j=newnext[j] endwhile if
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- kmp 算法
![提示](https://static.bdocx.com/images/bang_tan.gif)