KMP演算法及next陣列優化

2021-10-08 08:39:44 字數 2876 閱讀 3328

當目標串txt與模式串pat進行匹配時,如果txt[i]遇到不匹配的pat[j]時,不必像暴力匹配法那樣每次只將pat後移一位,然後又從其第一位和txt[i+1]進行比較。

因為如果pat[0]~pat[j-1]有公共前字尾的話,那麼txt[i]前的子串也必定存在乙個公共前字尾

那麼,我們可以將pat右移,使得從pat的字首匹配txt子串的字首,pat的字尾匹配txt子串的字尾,變為pat的字首匹配txt的字尾,這樣就不必每次都移動一位,然後重新開始匹配

上面提到的公共前字尾,應該為最長公共前字尾,因為公共前字尾越短,移動的越多,就有可能漏掉部分匹配,導致結果的出錯。

ababab的字首為,字尾為(不能是字串本身

它的最長公共字串即為『abab』.長度為4

pmt即 partial match table(部分匹配表),當前子串(pat[0]~pat[j])的最長公共前字尾例如「ababab"

charab

abab

index01

2345

pmt001234

public

static

int[

]getpmt

(string s0)

else

if(s[flag]

== s[i]

)else

if(s[flag]

!= s[i]

&& flag !=0)

}return pmt;

}

在當前字元pat[j]之前的子串(pat[0]~pat[j-1])的最長公共前字尾,那麼我們可以將pmt陣列整體右移一位且next[0]設為-1即可得到。

例如「ababab"

charab

abab

index01

2345

pmt001

234next-10

0123

遞迴得到

如果txt[i]和pat[j]不匹配,則將txt[i]與pat[next[j]]進行匹配

設next[j]的長度為length,則pat[length]為最長公共前字尾的下乙個元素之前的元素pat[0]~pat[length-1] (一共length個元素)依然和之前的txt的字尾相匹配。

package array;

/** * description

* author cloudr

* date 2020/7/20 23:13

* version 1.0

**/public

class

kmppublic

static

intkmpbynext

(string txt, string pat)

else

//匹配失敗則回溯

j = next[j];}

if(j == pat.

length()

)return i - j;

else

return-1

;}public

static

int[

]getnext

(string ps)

else

//不能匹配上

}return next;

}}

有txt=「aaaabcdef」,pat=「aaaaax」

s[i]和p[j]已經匹配失敗,下一步會與p[ next[j] ]相匹配,但是如果p[j] == p[ next[j] ],那麼後面s[i]和p[ next[j] ]的匹配也必然會失敗,所以我們將p[ next[j] ]之前的子串的最長公共前字尾next[ next[j] ]賦值給next[j]

public

static

int[

]getnext

(string s0)

else

}else

//不能匹配上

}return next;

}

基於pmt陣列(未成功,對於某些子串符匹配會陷入死迴圈,待填坑)

string haystack = 「mississippi」;

string needle = 「issip」;

class

solution

if(haystack.

charat

(i)== needle.

charat

(j))

else

j = j - pmt[j];}

if(j == needle.

length()

)return i - j;

else

return-1;}}

推薦閱讀參考[1][2]

KMP演算法 next陣列

通過上文完全可以對kmp演算法的原理有個清晰的了解,那麼下一步就是程式設計實現了,其中最重要的就是如何根據待匹配的模版字串求出對應每一位的最大相同前字尾的長度。我先給出我的 1 void makenext const char p,int next 214 next q k 15 16 現在我著重講...

KMP演算法 NEXT陣列

kmp和next陣列基本上是一起用的,有了next陣列,才有kmp演算法,講道理來說這兩個都是基於最大前字尾和,也就是說需要用到kmp的時候必須先把next陣列先求出來,next陣列就是由所匹配的word的每個子串的前字尾和最大匹配得到的,說實話next陣列的演算法給優化得已經很無解了,以至於至今我...

kmp演算法next例題 KMP演算法next陣列求解

kmp演算法與bf演算法的比較 bf演算法的想法十分樸素,即先將子串t的第一位與主串s的第一位對齊開始匹配,當不能匹配時將子串整體往後移一位,然後重新匹配,以此類推直至排出結果 如當遇到下圖所示情況時,需將子串整體後移一位,將i,j分別回溯到主串第2位和子串第一位。kmp演算法 對bf進行思考後,我...