KMP演算法總結與模板

2021-10-12 10:08:20 字數 1949 閱讀 5994

發現學了好久了kmp了,模板卻總是背不會,感覺自己還是沒有理解深刻,僅以此作為複習…

給定乙個模式串s長度為m,和模板串p長度為n,求解模板串p在模式串s**現的位置

模板串p需要同模式串s匹配很多次,當乙個字元匹配失效時,傳統的演算法往往模板串p會整個從頭開始,導致演算法的時間複雜度是o(m

∗n)o(m*n)

o(m∗n)

,kmp演算法通過構造模板串p的next陣列,使其進行"跳躍"著的匹配,將其時間複雜度優化到 o(m

+n)o(m + n)

o(m+n)

。next陣列

next[k] 含義:前k個元素具有相同前字尾的長度。

當第k個字元匹配失效時,應該跳轉到的下乙個位置為next[k]。因為雖然第k個字元匹配失效,但是前k個字元匹配成功,那麼此時已經匹配的字串的字尾就可以當作下一次匹配的字首,當然此處的前字尾相同且長度盡可能大,這樣的跳轉優化了複雜度。

例子:求 abababca 的 next陣列

charab

abab

caindex01

2345

67next

-10

010

340

next陣列的求法很多種,感覺我寫得比較古老…

觀察next陣列:

1)通常第乙個next[0] = -1

2)next[k]為前k個字元相同前字尾的長度,由於是長度,而下標是從0開始的,所以其實next[k]是跳轉到具有相同字首字串的後乙個字元進行下一次匹配的。

畫圖理解:

**求next

void

getnext

(char

*p)else j = next[j];}

}

next陣列的優化當第 p[ i ] 與 s 匹配失效時會跳轉到 next[ i ],但是如果 p[ i ] = p[next[ i ]],那麼匹配依然失效,所以需要遞迴的跳轉即next[ i ] = next[next[ i] ]

void

getnext

(char

* p)

else j = next[j];}

}

查詢p第一次出現在s的位置
int i =

0, j =0;

int m =

strlen

(s), n =

strlen

(p);

while

(i < m && j < n)

else j = next[j];}

// 模板串p的最後乙個字元p[n-1]匹配成功後,++j後j = n然後退出迴圈

if(j == n)

查詢p出現在s的所有位置
int i =

0, j =0;

// 注意 j = 0

while

(i < m)

else j = next[j];if

(j == n)

}

由於next陣列的含義是具有相同前字尾的長度,所以往往用來求迴圈節

使用方法:

1)求整個字串迴圈節長度 :r = n - next[n]

2)補全為迴圈節的不斷重複需要填充的字元個數:

當 r != n && n % r == 0 : cnt = 0

否則,cnt = r - n % r

3)求每個字首的迴圈節:i - next[ i ]

4)利用迴圈節不斷向前遞迴

KMP演算法模板與解析

全部資料結構 演算法及應用課內模板 將kmp演算法,就要先講講它是用來幹什麼的,為什麼叫這個名字,暴力的演算法又是怎樣的 kmp是三人knuth,morris,pratt,他們仨發明了這個演算法,所以叫kmp。不要驚訝。然後它是用來解決字串的模式匹配問題 大白話就是找子串 舉個例子說就是,給你乙個主...

KMP演算法(模板)

time limit 1000ms memory limit 65536k 有疑問?點這裡 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1 長度小於1000000 第二行代表string2 長...

KMP演算法模板

在文字t 1.n 中找到某個模式p 1.m 所有出現的位置被稱作字串匹配問題 m n p3375 模板 kmp字串匹配 這道題在洛谷上的評級居然是普及 普及?qvq 實現起來還是比較簡單的,只不過有很多細節可以有很多種寫法,看別人的 容易凌亂。理解起來比較困難的部分是如何get next 不建議初學...