演算法 字串匹配問題 KMP演算法

2021-09-26 22:23:59 字數 3067 閱讀 9765

假如有兩個字串,判斷乙個字串是否包含在另乙個字串裡面。

例如字串str1的內容為ceabcddeabcdef 

另乙個字串str2的內容為abcde

字串2包含在字串1裡面,那麼就返回true,否則返回false。

暴力匹配的思路比較簡單,好理解一點:

假設現在

str1

匹配到 i位置

,子串str2

匹配到

j 位置,則有:

1)如果當前字元匹配成功(

即str1[

i] ==

str2[j

]),則i++

,j++

,繼續匹配下乙個字元

2)如果失配(

即str1[

i]! =

str2[j

]),令i=

i- (j - 1)

,j = 0

。相當於每次匹配失敗時,

i回溯,

j 被置為0。

例如對於 str1 = ceabcddeabcdef ,str2 = abcde , str1現在已經匹配 i=1 ,即e的位置,j 每次都是從0開始的,str2的第乙個字元為a,無法匹配,i = i - (j - 1) = 1 - ( 0 -1 ) = 2, j 重新置為0,str1當 i = 2 的位置為a,str2 j =0的位置是a,匹配成功。然後 i++, j++,兩個字串都到了b的位置,匹配成功。i++, j++,兩個字串都到了c的位置,匹配成功。i++, j++,兩個字串都到了d的位置,匹配成功。i++, j++, str1匹配到了d,str2匹配到了e,匹配失敗了。需要重新進行匹配,i = 

i - (j - 1) = 6 - ( 4 -1 ) = 3,j = 0,重複上面的步驟,直到匹配成功。

public class violencematch 

//暴力匹配演算法實現

public static boolean violencematch(string str1, string str2)else

} //判斷是否匹配成功

用暴力方法解決的話就會有大量的回溯,每次只移動一位,若是不匹配,移動到下一位接著判斷,浪費了大量的時

間這裡有些概念需要知道,首先是字串的字首與字尾

字串的字首是指字串的任意首部,字串的字尾是指字串的任意尾部。

例如:

第二個概念是部分匹配值,所謂部分匹配值就是「字首」和「字尾」的最長的共有元素的長度(字首和字尾不包含串本身),我們以「abcdabd」為例:

那麼對於字串「abcdabd」,部分匹配值就是:

」部分匹配」的實質是:有時候,字串頭部和尾部會有重複。比如,」abcdab」之中有兩個」ab」,那麼它的」部分匹配值」就是2(」ab」的長度)。

kmp演算法的步驟

舉例來說,有乙個字串 str1 = 「bbc abcdab abcdabcdabde」,判斷,裡面是否包含另乙個字串 str2 = 「abcdabd」

2. 重複第一步,還是不符合,再後移。

3.一直重複,直到str1有乙個字元與str2的第乙個字元符合為止。

4.接著比較字串和搜尋詞的下乙個字元,還是符合。

5.遇到str1有乙個字元與str2對應的字元不符合。

7.怎麼做到把剛剛重複的步驟省略掉?可以對str2計算出一張「部分匹配表」,我們前面已經介紹過了方法。

8.已知空格與d不匹配時,前面六個字元」abcdab」是匹配的。查表可知,最後乙個匹配字元b對應的」部分匹配值」為2,因此按照下面的公式算出向後移動的位數:

移動位數 = 已匹配的字元數 - 對應的部分匹配值

因為 6 - 2 等於4,所以將搜尋詞向後移動 4 位。

10. 因為空格與a不匹配,繼續後移一位。

11. 逐位比較,直到發現c與d不匹配。於是,移動位數 = 6 - 2,繼續將搜尋詞向後移動 4 位。

next陣列

我們在前面已經得到了每個子串的部分匹配值,但是這個並不是next陣列的值,接下來將部分匹配值去掉最後乙個值,在開頭加上乙個 -1 ,然後整體往後移動 一格與模式們已經分析得到了其部分匹配值:

我們將部分匹配值的最後一位刪除: 

然後再第一位填上-1後整體後移1位:

最後將所有數字 +1,借的到了next陣列:

字串匹配問題 KMP匹配演算法

基本思想 字串匹配問題 在文字串中尋找是否有與模式串相同的子串 在字串匹配時,暴力匹配忽略了如果模式串開頭與中間有重複部分,在將模式串的後面的重複部分匹配後,無法繼續匹配的話,此時將模式串開頭實際上也已經被匹配了,可以直接從開頭重複部分之後開始匹配 這裡引入了乙個部分匹配值表,每個與模式串的字元對應...

字串匹配問題 KMP演算法

kmp演算法 kmp是解字串匹配這類題目的演算法,又稱 看毛片 演算法。如下圖,給定乙個長度為n的文字,給定乙個長度為m 的字串,求該字串在給定文字的中出現的次數。kmp就是解決這一類題目的。i 1 zzkzzzkzzzkzkkkz zzkzzkzzkzzk j 1繼續考慮上面的問題。首先我相信每個...

字串匹配問題 KMP演算法

字串匹配問題 給定兩個字串s 主串 和t 模式串 假設n strlen s strlen t m,判斷主串s中是否包含模式t,且返回t在s中所在的起始位置。這裡為簡單起見,若s包含t,則只返回第乙個t所在的位置。一般的蠻力法如下 蠻力法在遇到不匹配時,j每次都要回到t的起點,從新開始匹配,這樣來看效...