KMP 深入理解next數組

一、引言

  • KMP又稱模式匹配算法,能夠在線性時間內判定字符串A[1~N]是是否爲B[1 ~ M]的子串,並求出A在B中各次出現的位置。

二、基本含義

  • next數組:next[i] 代表A中以i結尾的非前綴子串(非前綴子串的意思就是不能和A完全相等的後綴子串) 與 A的前綴能夠匹配的最大長度。
  • 當不存在這樣的前綴串時,顯然next[i] = 0, 故next[1] = 0 (因爲第一個字符前面沒有字符串且第一個字符不是非前綴子串)
  • 我們可以讓A對B進行匹配,求出一個數組p。p[i]代表以i結尾的子串 與 A的前綴能夠匹配的最大長度。 當p[i] = n(A的長度)代表匹配此位置成功。

三、next數組的求解

1. 樸素的求解next數組

  • 假定A串爲 abababbc
    在這裏插入圖片描述

2. 優化求解next數組過程

在這裏插入圖片描述

void getNext() { //n串A串的長度
 for (int i = 2, j = 0; i <= n; i++) { //求解next[i] 
 	while (j && A[i] != A[j + 1]) j = ne[j]; //這時候找到一個符合的位置 A[i] == A[j + 1] 那麼就停止了。
 	if (A[i] == A[j + 1]) j++; //這時候有2種情況,j==0:代表前面的串都不滿足。 否則那麼next[i] = j + 1。
 	ne[i] = j; // 求解出ne[i] 。  
 }
}

三、kmp算法

  • 這時候我們與串B匹配的過程和求解next的過程大同小異。
void kmp() {
	for (int i = 1, j = 0; i <= m; i++) {
		while (j && B[i] != A[j + 1]) j = ne[j]; 
		if (B[i] == A[j + 1]) j++; //在前面已經匹配的長度的基礎上加1
		p[i] = j; //代表B串以i結尾的子串與 A的前綴的最大匹配長度 匹配串爲B[i - j + 1, i]
		//if (j == n) {//匹配成功 }
	}
}

四、其他應用

  • 最小循環節
    20200305215013672.png)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章