KMP演算法之while迴圈部分

2021-07-11 19:51:09 字數 1975 閱讀 7669

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後面...