一、简单模式匹配算法(略,逐字符比较即可)
二、KMP模式匹配算法
next数组:j为字符序号,从1开始。
(1)当j=1时,next=0;
(2)当存在前缀=后缀情况,next=相同字符数+1;
(3)当前缀 != 后缀且j != 1时,next=1。
如下:
abcdex
next=011111
abcabx
next=011123
ababaaaba
next=011234223
说明:0位置为情况1;
1、2位置为情况3;
3-5位置一直有前缀对称,所以一直累加;
6位置前缀不对称,j=next[ j ]找对称子串开始位置;如果没有继续j= next[ j ]直到 j = 0,next为0;
此处 i = 6, j = 4;第一次找: j = next[4] = 3, T[3] != T[6] ,没找到;第二次找: j= next[ 3 ] =1, T[2] == T[6], 找到累加 j+1 =2;
7位置同上;
8位置在7位置基础累加得到。
aaaaaaaab
next=012345678
说明:0位置为情况1;
1位置为情况3;
2-8位置一直有前缀对称,所以一直累加。
代码如下:
void get_next(char T[], int * next)
{
int i = 1;
int j = 0;
next[1] = 0;//条件(1)
while(i < getlength(T))
{
if(j == 0 || T[i] == T[j])
{
++j;
++i;
next[i] = j;//如果前缀一直有对称,则对称性累加
}
else
{
j = next[j];//如果前缀不对称,则从对称性开始的地方开始累加;
//如果仍然不对称,则继续从子子对称开始的地方开始累加;
}
}
}
三、KMP模式匹配算法改进
nextval数组:j为字符序号,从1开始。
(1)当j=1时,nextval=0;
(2)当存在前缀=后缀情况,nextval=相同字符数+1;如果该字符在后缀中,则nextval = 前缀中该字符的nextval值。
(3)当前缀 != 后缀且j != 1时,nextval=1。
如下:
ababaaaba
next= 011234223
nextval=010104210
aaaaaaaab
next= 012345678
nextval=000000008
ababaaaba
next= 011234223
nextval=010104210
代码如下:
void get_nextval(char T[], int * nextval)
{
int i = 1;
int j = 0;
nextval[1] = 0;//条件(1)
while(i < getlength(T))
{
if(j == 0 || T[i] == T[j])
{
++j;
++i;
if(T[i] != T[j])
nextval[i] = j;//条件(3),累加
else
nextval[i] = nextval[j];//条件(2)
}
else
{
j = nextval[j];//如果前缀不对称,则从对称性开始的地方开始累加;
//如果仍然不对称,则继续从子子对称开始的地方开始累加;
}
}
}