kmp演算法是一種改進的
字串匹配
演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為
克努特——
莫里斯——
普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。
關於kmp演算法的基本原理,這裡不再多做解釋。當時看的時候,最困惑的部分是演算法核心的乙個while迴圈,所以這裡也主要用乙個具體的例項來詳細講解這個while迴圈。先上一段**。
#includeusing namespace std;
int main()
if(str_des[k]==str_des[i])
next[i]=k;
} //結束構造next
for(int i=0,k=0;i0&&str_src[i]!=str_des[k])
if(str_src[i]==str_des[k])
if(k==len_des){
cout<<(i-k+2)《第41和53行的while迴圈是演算法的核心部分,個人感覺也是比較難理解的地方。
為了方便描述,接下來用s代替str_des陣列。
當我們在構造next陣列的時候,需要時刻比較的是s[i]和s[k]是否相等,如果兩者相等,簡單的將k++,再令next[i]=k,表明以s[i]字元結尾時,當前字首和字尾共有元素為k。
關鍵問題是遇到s[i]和s[k]不相等時,while迴圈是怎麼處理的!
考慮一下,當我們遇到s[i]!=s[k]時,真的沒有得到任何有用的資訊,只能讓k從0再來了嗎?其實,儘管s[i]!=s[k],但是我們可以知道,此時s[0]……s[k-1]和s[i-k]……s[i-1]這兩段是成功匹配上了的,考慮乙個具體的例子。 a
aaab
aaaa
a012
3456
789假設當i=9,k=4時,既然s[i]!=s[k],那麼說明當以s[i]結尾時,字首和字尾共有元素數量一定s[3]和s[5]->s[8]是匹配上了的。
(1)此時我們可以知道,s[0]=s[5],s[1]=s[6]……s[3]=s[8],見下表紅色標註陣列下標部分。
(2)由(1)的對應關係,為了更快速的得到next[i],我們就要充分利用s[0]->s[k-1]這段字串的字首字尾關係。所以我們先看一下以s[k-1]結尾時,前字尾共有元素數量,具體計算過程不再多寫,直接寫出結果——next[3]=3。根據while迴圈內的執行語句,則k=3,這個k第(4)步再用
先考慮next[3]=3帶給我們的資訊:s[0]=s[1],s[1]=s[2],s[2]=s[3]。
(3)結合(1)、(2),我們得到下表黃色標註部分
(4)再一次判斷s[i]和s[k]是否匹配,若不匹配,重複上述步驟(while迴圈)。
陣列下標01
2345
6
7
89字元
aaaa
baaa
aa陣列下標
0
1
2
3
陣列下標
待匹配
0
1
2
待匹配
現在應該已經發現了while迴圈的精髓所在—當s[i]!=s[k]時,充分利用next[k-1]的資訊,來快速的得到next[i]。
部分KMP演算法
include include 求字串定位 普通演算法 時間複雜度為 o m n 有事可達到o m n int index char s,char t,int pos k 0 無意義 為了下標更簡明 while i sl j tl 當j 0時候也要i 也要s中向後推一位 因為等於0時候說明從t中開頭...
python迴圈之while迴圈
python中迴圈有兩種,while和for迴圈。在while迴圈中,當while值為true時,while迴圈會一直進行下去 無限迴圈 直到當while值為false時,while迴圈才會停止。while迴圈結構 無限迴圈 a true while值 while a print hello,wor...
Python迴圈之while迴圈
while 條件 迴圈體我們先借助一小段 認識下while迴圈,得到它的基本原理 while true print 狼的 print 我們不一樣 print 愛情買賣 print 不將就 print 年少有為 我們知道,是自上而下執行的,當直譯器看到while它會幹什麼呢,它會先判斷你while後面...