字串匹配之KMP 全力解析

2021-06-21 14:50:03 字數 2083 閱讀 2877

1. 如果你現在完全不知道kmp是個神馬玩意,請先閱讀阮一峰的《字串匹配的kmp演算法》。

kmp演算法最難理解的是就是next陣列的計算過程,在此分享下我所理解的kmp演算法以及next陣列的計算過程(如果看前面理論比較頭大,可以先看後面例子的計算過程,在回過頭來看理論就會釋懷):

1. next陣列的計算過程: 

申明:next陣列下標從0算起, 定義next[0]=-1, next[1]=0; 模式串記為t[ ]

假如求 t中 j+1 位的next[j+1]:

將其 前一位(模式字元)的內容與其前一位的next值(next[j])的內容(t[next[j]])進行比較:

如果它們相等(t[j]==t[next[j]]),則next[j+1] = next[j]+1;

如果他們不相等,則繼續向前尋找,直到找到next值對應的內容與前一位相等為止,則在這個next值上加一;

如果直到第一位都沒有與之相等,則next[j+1] = 0;           

例: 有模式串 "abaababc"

j=0時,next[0] = -1 ; j=1時,next[1] = 0;

j=2時,t1!=t0, k=next[0]=-1, next[2]=0;

j=3時,t2==t0, next[3] = next[2]+1 = 1;

j=4時,k=next[3]=1, t3!=t[1], k=next[1]=0, t[3]==t[0], next[4]=next[1]+1 = 1;

j=5時,k=next[4]=1, t[4]==t[1], next[5]=next[4]+1=2;

j=6時,k=next[5]=2, t[5]==t[2], next[6]=next[5]+1=3;

j=7時,k=next[6]=3, t[6]!=t[3], k=next[3]=1, t[6]==t[1], next[7]=next[3]+1 = 2;

2. 上述演算法的實現:

[cpp]view plain

copy

//update 2014-04-19 10:08

void

calnext(

const

char

*t, 

int*next)  

else

k = next[k];  

}  

3. kmp主演算法:

設定比較起始下標: i=0, j=0;

迴圈直到 i+m>n 或者 t中所有字元都以比較完畢

a. 如果 s[i]==t[j], 則繼續比較s和t的下乙個字元; 否則

b. 將 j=next[j], 從這位置開始繼續進行比較;

c. 如果j==-1, 則將 i 和 j 分別加1, 繼續比較;

如果t中所有字元均比較完畢,則返回匹配的起始下標,否則返回-1;

4. kmp演算法實現:

[cpp]view plain

copy

//update 2014-04-19 10:08

intkmpmatch(

const

char

*s, 

const

char

*t)  

}  return

-1;  

}  

舉例: 設主串 s="ababcabcacbab", 模式 t="abcac"

按照上述方法計算得next=

本篇文章主要關注next陣列的計算及kmp主演算法的實現,如果要了解next陣列是什麼,為什麼要這麼計算next陣列,請見

如果你覺得本篇對你有收穫,請幫頂。

swalge

字串匹配之KMP 全力解析

1.如果你現在完全不知道kmp是個神馬玩意,請先閱讀阮一峰的 字串匹配的kmp演算法 kmp演算法最難理解的是就是next陣列的計算過程,在此分享下我所理解的kmp演算法以及next陣列的計算過程 如果看前面理論比較頭大,可以先看後面例子的計算過程,在回過頭來看理論就會釋懷 1.next陣列的計算過...

字串匹配之KMP 全力解析

近日,一同學面試被問到字串匹配演算法,結果由於他使用了暴力法,直接就跪了。字串匹配方法大概有 bf 暴力破解法 簡化版的bm,kmp,bm,一般情況下,大家聽說最多的應該就是kmp演算法了。之前學習過,由於時間間隔比較大,記不太清楚了,今天上網查了下,發現寫kmp的文章是不少,但是真正清晰簡潔就沒有...

字串匹配之KMP 全力解析

1.如果你現在完全不知道kmp是個神馬玩意,請先閱讀阮一峰的 字串匹配的kmp演算法 kmp演算法最難理解的是就是next陣列的計算過程,在此分享下我所理解的kmp演算法以及next陣列的計算過程 如果看前面理論比較頭大,可以先看後面例子的計算過程,在回過頭來看理論就會釋懷 1.next陣列的計算過...