KMP算法過程及C++代碼

KMP算法思想

KMP算法是D.E.Knuth,J.H.Morris和V.R.Pratt共同提出的,簡稱爲KMP算法。
該算法較BF算法有較大的改進每當一趟匹配過程中出現字符不相等時,主串指示器 i 不用回溯,而是利用已經得到的“部分匹配”結果,將模式串向右“滑動”儘可能遠的一段距離後,與 i 對齊,繼續進行比較。

KMP算法過程示例

在這裏插入圖片描述
當 i = 3,j = 3時失配。
此時按照BF算法,將子串P右移一位:

在這裏插入圖片描述

按照KMP算法,儘可能的多移幾位,i 的位置不變,使得模式P中的某個位置繼續與 i 進行比較
在這裏插入圖片描述
發現當 i = 7,j = 5時失配:
在這裏插入圖片描述
模式P繼續向右滑動,進行第三次匹配:
在這裏插入圖片描述
此時匹配完成。

確定next[ ] 函數

在這裏插入圖片描述

因此我們需要對模板s[ ]進行預處理:
以 i 爲終點的後綴 = 從1開始的前綴,且長度最長
在這裏插入圖片描述
即next[ i ] = j :
s[ 1…j ]這一段 = s[ i-j+1 … i ] 這一段

C++代碼實現

注:s[ ]下標從1開始,p[ ]下標從0開始,所以s[ i ] 對應的是p[ j+1 ]

#include<iostream>
#define N 10010
#define M 100010

using namespace std;

int main()
{
	int n, m;
    	char s[M], p[N];
 	int ne[N];
	 
	cin >> n >> p+1 >> m >> s+1;
 
 	for(int i = 2, j = 0; i <= n; i++) //求出 next[]
 	{
  		while(j && p[i] != p[j+1])
   			j = ne[j];
		if(p[i] == p[j+1])
   			j++;
 		ne[i] = j;
 	}
 	
 	for(int i = 1, j = 0; i <= m; i++) //KMP算法
 	{
 		while(j && s[i] != p[j+1])
   			j = ne[j];
  		if(s[i] == p[j+1])
  			 j++;
  		if(j == n)
  		{
   			printf("%d ", i-n);
   			j = ne[j];
 		 }
 	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章