线性表-串:KMP模式匹配算法

一、简单模式匹配算法(略,逐字符比较即可)


二、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];//如果前缀不对称,则从对称性开始的地方开始累加;
				       //如果仍然不对称,则继续从子子对称开始的地方开始累加;
		}
	}
}




你可能感兴趣的:(Datastructure)