資料結構 串的樸素模式和KMP匹配演算法

2021-08-03 10:20:39 字數 1947 閱讀 4841

一、樸素模式

假設我們要從主串s=」goodgoogle"中找到子串t=「google"的位置,步驟如下:

i表示主串的當前位置下標,j表示子串的當前位置下標,如上圖在第一輪比較(i=1開始)中j=4和i=4的位置不匹配,接下來就要指標回退,從i=2開始比較,如下:

如此反覆直到比較到 i =(主串長度-子串長度+1)的位置或者 j = 子串的長度 就退出比較迴圈,上面的主串和子串在比較到i=5的位置就完全匹配了。

}  //j>t[0]則說明子串被完全匹配

if( j > t[0]) 

return

i - t[0];  

else

return

0;  

}  int

main();   

char

t = ;  

inti = index(s, t, 1);  

printf("%d\n"

, i);  

return

0;  

}  

分析一下這種匹配演算法最好的情況時間複雜度是o(1)只需要一次比較,最壞的情況是每次最後乙個字元不匹配,時間複雜度是o(m*n) m是主串長度n是子串的長度。

二、kmp演算法

像二進位制這樣的多個0和1重複的字串,上面的模式匹配需要挨個遍歷是非常慢的,kmp演算法可以大大避免重複遍歷的情況。

下面我們來看看kmp演算法的基本原理

如上,可以看到主串s和子串t在第一輪比較的時候,前面5個相等,只有i=6和j=6的位置不等。由於子串t中abcde這5個字元本身互不相等,可以知道子串t中a就不可能和j=2、3、4、5的位置的字元相等。所以可以直接跳到i=6的位置進行比較。

再看上圖,如果子串t中存在重複的元素(比如j=1,2和j=4,5處的字元),按照上面的分析,我們可以直接跳到i=4的位置比較,但是我們已經知道j=1,2和j=4,5相等,並且i=4,5和j=4,5相等,所以可以不用比較i=4,5和j=1,2。

kmp模式匹配演算法就是為了不讓i指標回退,既然i值不回退,我們就要考慮變化j的值了。通過上面的觀察可以發現,j值的變化與主串其實沒有什麼關係,而是取決於子串t中是否有重複問題。

我們把t串各個位置的j值的變化定義為乙個陣列next,那麼next的長度就是t串的長度,可以得到下面函式:

資料結構 串的模式匹配 KMP演算法

目錄概念 簡述kmp演算法原理 計算next陣列 kmp演算法 測試 改進kmp演算法簡介 從s中匹配t串,在bf演算法中,通過指標回溯不斷進行匹配,其思想是窮舉。效率很低,但有些串有一定的規律,不需要回溯s串的指標,這就是kmp演算法。比如 s aaaaaab t aaab 在進行比較時,如果按照...

資料結構04 串的樸素匹配

在串的問題裡,匹配是很重要的一類問題。匹配是在乙個給定的主串中尋找乙個相同的子串,確定子串出現的位置。乙個樸素的做法是,將主串和子串逐字元比較。用指標移動兩字元。步驟如下 1 有兩指標,其中乙個i指向主串查詢的位置,另外j乙個指標指向子串的首位。2 比較兩指標所指的字元。如果相同,兩指標都移動一位。...

資料結構例程 串的模式匹配(KMP演算法)

本文針對資料結構基礎系列網路課程 4 串中第5課時串的模式匹配 kmp演算法 kmp演算法 include include sqstring.h void getnext sqstring t,int next 由模式串t求出next值 else k next k int kmpindex sqst...