KMP演算法分析

2022-08-24 17:30:28 字數 2105 閱讀 8798

根據博主july的所載,記錄個人理解心得(紅色部分為個人理解):

1.kmp演算法流程

假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置

1.如果j = -1,或者當前字元匹配成功(即s[i] == p[j]),都令i++,j++,繼續匹配下乙個字元;(當s[i]==p[j]時,說明模式串j前面的字元都與文字串i前面對應的字元匹配成功)

2.如果j != -1,且當前字元匹配失敗(即s[i] != p[j]),則令 i 不變,j = next[j]。此舉意味著失配時,模式串p相對於文字串s向右移動了j - next [j] 位。(next[j]為j前面字元所擁有的相同的最大字首和字尾)

即當匹配失敗時,模式串向右移動的位數為:失配字元所在位置 - 失配字元對應的next值,即移動的實際位數為:j - next[j],且此值大於等於1

如果next [j] 等於0或-1,則跳到模式串的開頭字元,若next [j] = k 且 k > 0,代表下次匹配跳到j 之前的某個字元,而不是跳到開頭,且具體跳過了k 個字元。

int kmpsearch(char* s, char*p)

else

}if (j == plen) //返回模式串在文字串的起始位置(當j==plen時,說明已經匹配完成,所以其在文字串的起始點為i-j)

return i -j;

else

return -1

;}

2. 字首字尾最長公共元素長度

公式:p0 p1 ...pk-1 pk = pj- k pj-k+1...pj-1 pj

(左右兩邊原因下標相加為j)

所以最大長度為k+1(因為是從0開始計數,到k結束)

如:

陣列的next[i](0~i)值,表示的是當前字元之前的最大相同前字尾的值,如next[9]指的是abcdefgab的最大相同前字尾;相當於最大相同前字尾平移1位,然後補-1;

3. next陣列匹配

匹配失配,j=next[j],模式串向右移動的位數為:j-next[j]。換言之,當模式串的字尾pj-k pj-k+1, ..., pj-1 跟文字串si-k si-k+1, ..., si-1匹配成功,但pj 跟si匹配失敗時,因為next[j] = k,相當於在不包含pj的模式串中有最大長度為k 的相同字首字尾,即p0 p1 ...pk-1 = pj-k pj-k+1...pj-1,故令j=next[j],從而讓模式串右移j- next[j] 位,使得模式串的字首p0 p1, ..., pk-1對應著文字串 si-k si-k+1, ..., si-1,而後讓pk 跟si 繼續匹配。如下圖所示:

4 程式

1 #include 2 #include 

3 #include 4

5void getnext(char *str,int

next)623

else

24 next[j]=next[k];25}

26else

2730}31

}3233int kmp(char *s,char *t)

3450

else

51 j=next[j];52}

53if(j==len2)

54return i-j;

55else

56return -1;57

}5859int

main()

60

---------------------

感謝博主v_july_v

原文: 

KMP演算法分析 java

如果用暴力匹配的思路,並假設現在str1匹配到 i 位置,子串str2匹配到 j 位置,則有 如果當前字元匹配成功 即str1 i str2 j 則i j 繼續匹配下乙個字元 如果失配 即str1 i str2 j 令i i j 1 j 0。相當於每次匹配失敗時,i 回溯,j 被置為0。用暴力方法解...

KMP演算法的效率分析

上一節,我們研究了kmp演算法的實現原理,這節,我們從分析的角度看看kmp演算法的時間複雜度和它的正確性。我們先看計算匹配字串最長字尾陣列的的函式 private intgetlongestsuffix int s throws exception if pi s 1 pi s 0 int k ge...

KMP 演算法,分析及遞迴實現

額,因為在準備考研,基本上不部落格了,重新遇到了kmp演算法,心血來潮,所以就來搗鼓一下了,沒錯,我來裝 x 的 我的麒麟臂在早已飢渴難耐了。想必來看kmp演算法的人,都知道kmp演算法是拿來幹嘛的,實現字串模式匹配的高效演算法,不過拿去其他模式匹配應該也可以,只要你想得到。現在再重述一遍演算法思想...