kmp算法Word格式文档下载.docx
- 文档编号:15912538
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:24
- 大小:29.84KB
kmp算法Word格式文档下载.docx
《kmp算法Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《kmp算法Word格式文档下载.docx(24页珍藏版)》请在冰豆网上搜索。
由此,我们得到关系式
‘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<
j),
‘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
1
2
3
4
5
6
7
8
9
p(i)
a
b
c
d
next[i]
-1
但是,如果此时发现p(i)==p(k),那么应当将相应的next[i]的值更改为next[k]的值。
经过优化后可以得到下面的表格:
优化的next[i]
附:
KMP算法查找串S中含串P的个数count
#include<
iostream>
stdlib.h>
vector>
usingnamespacestd;
inlinevoidNEXT(conststring&
T,vector<
int>
&
next)
{
//按模式串生成vector,next(T.size())
next[0]=-1;
for(inti=1;
i<
T.size();
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.size());
NEXT(T,next);
string:
size_typeindex,count=0;
for(index=0;
index<
S.size();
++index){
intpos=0;
size_typeiter=index;
while(pos<
T.size()&
iter<
S.size()){
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"
size_typecount=COUNT_KMP(S,T);
cout<
<
count<
endl;
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:
Begin
j:
=1;
k:
=0;
whilej<
Length(t)do
begin
if(k=0)or(t[j]=t[k])then
=j+1;
=k+1;
next[j]:
=k;
end
elsek:
=next[k];
end;
End;
Functionindex(s:
t:
string):
i,j:
get_next(t);
index:
i:
j:
while(i<
=Length(s))and(j<
=Length(t))do
if(j=0)or(s[i]=t[j])then
=i+1;
elsej:
=next[j];
ifj>
Length(t)thenindex:
=i-Length(t);
BEGIN
ClrScr;
{清屏,可不要}
Write(‘s=’);
Readln(str_s);
Write(‘t=’);
Readln(str_t);
=index(str_s,str_t);
ifint_i<
>
0then
Writeln('
Found'
str_t,'
in'
str_s,'
at'
int_i,'
.'
);
else
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,则模式串右移j-next(j)位,检查T[i]和W[next(j)]是否匹配。
重复此过程直到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
i=1
j=1
whilei<
=ndo
whilej<
0andW[j]<
T[i]do
j=newnext[j]
endwhile
if
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- kmp 算法
