1. 程式人生 > >KMP演算法詳解, 關於NEXT陣列及其改進

KMP演算法詳解, 關於NEXT陣列及其改進

關於KMP的總結


1.nextval陣列 
具體含義:
abcdefabc
在第二個c處匹配失敗 則應將j匹配到c上 即為j = 2 = 最大部分匹配長度;


這裡給出程式碼
void get_nextval()
{
	nextval[0] == -1; //初變數不得為0 注意思考將j移到首位的命令與移動i的命令的區別
	int i = 0; //為next賦值  因在下面迴圈中每次迴圈給next[i + 1]賦值 故初值為0
	int j = -1;/* 當第一次迴圈或j追溯到next[0] 應有next[i] = 0 使其回到首位
			   而當Ti] = Tj]時 最大部分匹配子串長度加1;
			   此時發現若j初值為-1 上述三種情況程式碼可合併 於是有此初值*/
	while(i < len - 1) //len為子串T長度
	{
	if(j == -1 || T[i] == T[j]
	{
		i++; //為i + 1賦值
		j++;//子串長度+1 或是 為使j由-1到0;
		if(T[j] == T[i])
			nextval[[i] = nextval[j]; //①此語句放到下面講解
		else
			nextval[i] = j;
	}
	else
		j = nextval[j];/*若是T[j] != T[i] 則應試圖尋找T[j] = T[i], 因nextval[j]早已求得 
					   則若滿足條件T[j]存在 應在一個T[j]前面有兩個部分匹配子串 
					   不好言述  可想象構圖 有兩個部分匹配子串 每個子串又有兩個匹配子串 則有可能第一個子串跟第四個
					   子串匹配, 找尋第一個子串的方法便是回溯j;
					   若無法找到 最後應令j = -1以執行if語句  上述程式碼已滿足 無需多言 */
	}
}





關於①的解釋:例如abcabcd 若匹配到第二個c匹配失敗 按照舊版next求法 直接令nextval[i] = j, 則此時會繼續匹配第一個c
而此時這個操作是百分之百無效的
於是在此進行改進 直接跳過此無效操作
此處改動更有效的針對aaaaaaaaab這種子串

關於KMP主函式
明確一點:KMP原始碼尋找的是第一個匹配子串 有時須根據條件略微改動KMP
詳見SDUT 3311;


小結:這只是資料結構初學者對於KMP的一些小心得
只是特別說明了一下自己之前困惑的地方 
祝各位共同進步 ~
·