KMP字串匹配演算法詳解

2021-09-29 22:43:18 字數 3303 閱讀 3968

kmp演算法利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度o(m+n)。

例如:第 j+1 個字元的next函式值next[j+1]等於3,意味著它的前三個字串,s[j-2]s[j-1]s[j] =s[0]s[1]s[2]。

例一:模式串:abcaabcba

下標0

1

2

3

4

5

6

7

8

模式串a

b

c

a

a

b

c

b

a

next值

-1

0

0

0

1

1

2

3

0

1.第乙個字元的next值令為-1。令第二個字元b的next值為0。初始k=0,j=1。開始比較s[k] 和s[j]。

2.比較s[0] !=s[1],所以j++,k不變,next[j=2]=k=0。

3.比較s[0] !=s[2],所以j++,k不變,next[j=3]=k=0。

4.比較s[0]==s[3],所以j++,k++,next[j=4]=k=1。

5.k=1了,所以比較s[1] !=s[4],k返回到next[k]位置,即k=next[1]=0,然後比較s[k=0] == s[4],所以 j++,k++,next[j=5]=k=1。

6.比較s[1]==s[5],所以j++,k++,next[6]=k=2。

7.比較s[2]==s[6],所以j++,k++,next[7]=k=3。

8.比較s[3] !=s[7],所以k返回到next[k=3]位置,即k=next[3]=0,然後比較s[k=0] !=s[7],所以j++,k=0不變,next[8]=k=0。

在例一中,每次不相等時返回的都是k=next[k]=0,都是返回到了開頭,下面乙個不是返回到開頭0的情況:

例二:模式串:aabcaaabaac

下標0

1

2

3

4

5

6

7

8

9

10

模式串a

a

b

c

a

a

a

b

a

a

c

next值

-1

0

1

0

0

1

2

2

3

1

2

從 j=5,k=1的時候開始

5.比較s[1]==s[5],所以j++,k++,next[j=6]=k=2。

6.比較s[2] !=s[6],所以k返回到next[k=2]位置,即k=next[2]=1,然後比較s[k=1]==s[6],所以 j++,k++,next[7]=k=2。

因此,發現k的退回是退回到next[k]的位置,即s[j]!=s[k]時,k=next[k]。

和bf演算法相比,kmp演算法主要是在模式串上下功夫,通過先求得模式串對應的next[ ]陣列,當兩個字串中字元匹配失敗時候將模式串的下標回溯到next[ ]中儲存的下標位置,而bf演算法是直接回溯到模式串的0下標,即開始第乙個字元。所以kmp演算法的時間複雜度要比bf演算法好。

1 #include2 #include34

char* s = "

aabcaaabaac";

5char* t = "

aac";6

7int next[100]; //

定義next陣列 89

void getnext(char *s, int

next)

1023

else

//若不匹配,即p[j]!=p[k],k=next[k]

24 k =next[k];25}

26}2728

int kmp(char* s, char*t)

2941

else

4246}47

if(j >=tlength)

48return i -tlength;

49else

50return0;

51}5253

intmain()

54

字串匹配演算法 KMP詳解

這兩天在看字串匹配演算法,第一次看到kmp演算法的時候覺得很難。於是上網搜分析,網上講kmp的演算法很多,只是好像很多都講的雲裡霧裡的,不甚清晰。後來想想還是找教材看看,第一回看的是 演算法 第四版,其實沒看懂 於是再找來clrs看,恍然大悟,果然還是clrs 好。本文主要是梳理一下整個思路,盡自己...

字串KMP匹配演算法詳解

下面我再來舉個具體例子,並給出一具體執行程式 對於目的字串big是banananobano,要匹配的字串small是nano,的情況,下面是匹配過程,原理很簡單,只要先和big字串的第乙個字元比較,如果相同就比較下乙個字元 他們的第二個字元 如果不同就把small整體右移乙個,之後再從small的第...

字串匹配KMP演算法詳解。

一 什麼是kmp演算法 假設現在有這樣乙個問題 有乙個文字串s,和乙個模式串p,現在要判斷s中是否有和p匹配的子串,並查詢p在s中的位置,怎麼解決呢?如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有 如果當前字元匹配成功 即s i p j 則i j 繼續匹配下...