如何理解KMP演算法

2021-10-05 16:36:21 字數 2147 閱讀 6481

kmp演算法的核心思想:設法讓主串不回退,讓子串回退的更少

整個過程分為兩步:

為子串建立一張最長匹配長度的表

利用這種表的索引對主串實現匹配判斷

測試樣本:

主串:"fsaabababzabababaaba"

子串:"abababzabababa"

規則:對每個子字串 [0…i],算出其「相匹配的字首與字尾中,最長的字串的長度」。例如:

當i=5時,對子字串ababab來說

字首:a、ab、aba、abab、ababa

字尾:b、ab、bab、abab、babab

此時最長匹配長度為4,匹配項為abab,同時其中同時看到另外乙個匹配項ab

了解了這張表的來歷,那麼應該怎樣簡化運算來求解最後一位a的最長匹配長度呢?

當i=12時,對子字串 abababzababab 來說,

字首:a, ab, aba, abab, ababa, ababab, abababz, ...

字尾:b, ab, bab, abab, babab, ababab, zababab, ...

子字串abababzababab字首字尾最大匹配了6個(ababab),那次大匹配了多少呢?容易看出次大匹配了4個(abab),更仔細地觀察可以發現,次大匹配的字首字尾只可能在 ababab 中,所以次大匹配數就是 ababab 的最大匹配數!第三大同理,可得abab的最大匹配數,查表可得該值為2。

?處找最大匹配發現結尾不是z,所以就不能直接6+1=7,應該找次大匹配,發現剛好對上abab後的字元a,所以?為4+1=5,匹配項為abab

到此為止,第一步已經完成了

**如下:

// 構造 pattern 的最大匹配數表

public

static

int[

]calculatemaxmatchlengths

(string pattern)

if(pattern.

charat

(i)== pattern.

charat

(maxlength)

) maxmatchlengths[i]

= maxlength;

}return maxmatchlengths;

}

既然子串的表已經建立,那麼下一步就是對主串使用了

首先,主串是不回退的,所以這裡用for迴圈實現從頭到尾的遍歷,同時對應尋找子串的最大匹配

在迴圈內部分三種情況執行:

部分匹配成功,指標i和count往後移動

匹配失敗,改變count,尋找次大匹配

完全匹配成功,記錄位置

public

static list

kmp_search

(string text,string pattern)

if(pattern.

charat

(count)

== text.

charat

(i))

if(count == pattern.

length()

)}return positions;

}

好了,到此為止kmp演算法的核心已經寫完了,下面開始測試:

理解KMP演算法

由暴力匹配引入kmp演算法 問題 有乙個文字串s,和乙個模式串p,現在要查詢p在s中的位置。如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有 示例 上面s,下面p 比如從a這裡開始匹配上了 一直這樣匹配下去 到這裡匹配不上了 就回滾回去重新開始 這種回滾的問題...

理解KMP演算法(引用)

理解kmp演算法 引用 通用性的kmp演算法 void getnext st t,int next 由子串t求出next值 else k next k 滑動過程中如果出現不相等則認為以k個字元相等進行下一次滑動 kmpindex st s,st t,int pos maxstrlen為一常量,用來定...

KMP 演算法(個人理解)

相信大家看了 matrix67 的講解,一定已經知道了 kmp 演算法是怎麼回事,怎麼操作的,為什麼時間複雜度不高 這裡,我主要是分享我對 kmp 的理解 kmp 的精髓是什麼?這個東西,各自有個字的理解,很多人都覺得是避免了重複匹配,而我的理解是預處理 為什麼是預處理?你看看 kmp 的執行過程 ...