2.KMP算法(找最长公共前后缀)

数据结构(知识点碎片十)_递归

对于模式串T =‘abaabc'

当第6个元素匹配失败时,可令主串指针i不变,模式串指针j=3

当第5个元素匹配失败时,可令主串指针i不变,模式串指针j=2

当第4个元素匹配失败时,可令主串指针i不变,模式串指针j=2

当第3个元素匹配失败时,可令主串指针i不变,模式串指针j=1

当第2个元素匹配失败时,可令主串指针i不变,模式串指针j=1

当第1个元素匹配失败时,匹配下一个相邻子串,令j=0, i++,j++

数据结构(知识点碎片十)_next数组_02

  • next数组

数据结构(知识点碎片十)_最长公共前后缀_03

void getNext(Str substr, int next[])
{
int j=1, t; 
next[1] = 0;
while(j < substr.length) //判断的是j+1的值,若条件为等于就越界了
{
if(t==0||substr.ch[j] == substr.ch[t]) //该判断包含了t等于0的情况
{
next[j+1] = t+1;
++t;
++j;
}
else
t = next[t];
}
}

int	KMP(Str str, Str substr, int next[])
{	
int i=1,j=1;
while(i<=str.length && j<=substr.length) //在主串和模式串的范围以内
{
if(j==0||str.ch[i]==substr.ch[j])
{
++i;
++j;
}
else
{
j=next[j];
}
}
if(j>substr.length)
return i-substr.length; 
else
return 0;
}
  • 改进KMP算法(求解nextval数组)

数据结构(知识点碎片十)_KMP算法_04

求解nextval数组:

  1. 当j等于1时,nextval[j]赋值为0,作为特殊标记;
  2. 当j大于1时:
  • 若 P¡ 不等于Pnext[j],则nextval[j] 等于 next[j];
  • 若 Pj 等于 Pnext[j],则nextval[j] 等于 nextval[next[j]]。(递归)

数据结构(知识点碎片十)_最长公共前后缀_05

void getNext(Str substr, int next[],int nextval[], int next[])
{
int j=1,t=0; 
next[1] = 0;
while(j<substr.length)
{
if(t==0 || substr.ch[j] == substr.ch[t])
{
next[j+1] = t+1		
if(substr.ch[j+1]!=substr.ch [next[j+1]])	
nextval[j+1] = next[j+1];
else
nextval[j+1] = nextval[next[j+1]];
++j;
++t;
}
else
t = nextval[t];
}
}

数据结构(知识点碎片十)_next数组_06