kmp算法.docx

上传人:b****4 文档编号:3001560 上传时间:2022-11-17 格式:DOCX 页数:24 大小:29.84KB
下载 相关 举报
kmp算法.docx_第1页
第1页 / 共24页
kmp算法.docx_第2页
第2页 / 共24页
kmp算法.docx_第3页
第3页 / 共24页
kmp算法.docx_第4页
第4页 / 共24页
kmp算法.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

kmp算法.docx

《kmp算法.docx》由会员分享,可在线阅读,更多相关《kmp算法.docx(24页珍藏版)》请在冰豆网上搜索。

kmp算法.docx

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&next)

  {

  //按模式串生成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非空,

  vectornext(T.size());

  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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1