1. 程式人生 > >關於KMP算法中,獲取next數組算法的理解

關於KMP算法中,獲取next數組算法的理解

AR 詳解 ID 獲取 char* kmp算法 特殊 lse blog

參考:KMP入門級別算法詳解--終於解決了(next數組詳解)

https://blog.csdn.net/lee18254290736/article/details/77278769

在這裏討論的next數組的含義為模式串p[j]之前前綴和後綴相等的個數,若都不相等則為0。(特殊情況,沒有前綴和後綴時,則為-1,如next[0]=-1;當j==1時,p[1]前面只有一個字符,在這裏認為next[1]=0)

以下是計算next數組算法的代碼:

void getNext(char *p, int *next)
{
	int j=0, k=-1;
	next[0] = -1; 
	while (j<strlen(p) - 1)
	{
		if (k == -1 || p[j] == p[k])     
		{
			++j;  ++k;
			next[j] = k;
		}
		else                      
			k = next[k];
	}
}

對以上代碼的解析:

首先,k 始終代表著模式串中當前j對應的p[j]之前前綴和後綴相等的個數,因此p[j] == p[k]時

++j;  ++k;
next[j] = k;

當p[j] != p[k],則

k = next[k];

此時k 依然代表著模式串中當前j對應的p[j]之前前綴和後綴相等的個數,只不過個數變少了,例如p[j]之前的字符串為acac.....acac,p[j]之前前綴和後綴相等的個數為4,則k=next[4]=2,則可視為ac.........ac。當p[j]還是不等於p[k]時,再次執行

k = next[k];

直至它們相等,或k==-1。當k==-1時,必定執行if語句中的代碼,使得當前next[j]=0。

以上就是對獲取next數組算法的理解。

配合以下代碼實現KMP算法:

int kmp(char* W,char* T,int* next){
	int i = 0, j = 0;
	while (i<strlen(T)){
		while (j != -1 && W[j] != T[i]){ j = next[j]; }
		if (j == strlen(W)-1){
			return i - strlen(W) + 1;
		}
		else{
			j++;
			i++;
		}
	}
	return -1;
}

關於KMP算法中,獲取next數組算法的理解