關於KMP的筆記

2021-10-25 06:39:13 字數 1786 閱讀 7077

今天資料結構課上講了kmp演算法,課上不是很理解,現在在紙上推算了一遍寫下來以供將來複習用。

void

getnext

(char s2,

int next)

else}}

intkmp

(char s1,

char s2,

int next)

else}if

(j == lens2)

else

}int

main()

;char s1[

100]

, s2[

100]

; cin >> s1 >> s2;

getnext

(s2, next)

; cout <<

kmp(s1, s2, next)

;return0;

}

首先宣告,next陣列表示我將目標串s與模擬串t一位位對比時讀到第i個s與t不同,就向前將第next[i]個拽過來取代t中的i與s對齊。注意因為next陣列不用管目標串,只有模擬串本身就可以寫出他對應的next陣列,所以我沒法考慮第i個和第next[i]個是不是相同以及是不是與s中的相同,所以寫出來代表的只是next[i]向前到頭與i向前相同位數對應全等,不包括他們自己。例如:

綜上,next陣列給出了在第i個位置不相同時,向前回溯拉至此時i的位置的索引,特徵是這兩個元素之前擁有相同的一段序列且前面的這段序列(下面我們把它叫做最長相同序列)一直到頭。

下面先說有了next陣列後怎樣程式化實現,即kmp函式。

ps一點:因為next表示在j之前擁有公共相同序列的位置,所以遞推一次後的j一定是減小的。

int

kmp(

char s1,

char s2,

int next)

//i,j是目前讀到的位置,對應元素相同則再去比下一位置,所以

//s1[i] == s2[j]時,i,j++;而當j=-1時,說明從原本讀到的j向前,

//每乙個有最長相同序列的位置本身的元素與s1中的不相等,或者根本沒有

//最長相同序列。這樣一直會到0.而next[0]一定為-1,此時應該把s2整體

//拉至i的後面,故此時的i對應j為-1,j為0時i已經++了。

else

//此時的j1與s1中的不相等,那麼看j2是否相等,以此類推。}if

(j == lens2)

//因為j=next[j]此遞推是遞減的,所以想要j走到頭一定是通過

//s1[i]=s2[j]那部分走下來,所以j到頭說明此時全等。

else

}

得到next陣列的函式:

假如此時前i已經得到了next值,next[i]=j1(假定此時j=j1),那麼從j1往前一直到頭(p2~p1)等於i前面相同長度的片段。(此時的工作都是為了求?即i+1處的next值)。此時迴圈:i掌握kmp乙個是理解利用已走過的相同序列的原理,前i個next已知後第i+1個可以利用前i個的已知資訊,利用了dp的思想。另外,kmp目前並不是最快的演算法,後來的bm演算法以及sunday演算法都要優於它。

關於KMP演算法的筆記

以前一直沒有搞懂kmp演算法,突然心血來潮,特意去網上搜尋資料下定決心弄懂,終於在一篇文章的幫助下,對kmp演算法有了自己的理解。這篇文章的出處是 the knuth morris pratt algorithm in my own words 一 什麼是kmp演算法?kmp演算法是一種改進的字串匹...

關於KMP學習筆記 2019 7 26

網上一堆 形象 部落格浪費我一堆時間,果然以前摸的魚現在還得還qaq 我來講我對於kmp演算法的自己理解 首先宣告一下,kmp演算法最關鍵的地方不在於匹配,而在於求模式串的最長匹配前字尾,在網上的其他部落格上,這個 最長匹配前字尾 的名字被替換成了 nxt 而導致部落格十分的 好懂 wdnmd我怎麼...

關於KMP演算法

複習的時候隨便寫寫的,用git太麻煩,就用csdn儲存下。kmp演算法寫起來很短,但是精髓是它的思想不太好理解,主串不用回溯,是因為模式串自己與自己比較匹配可以得出相應的next值,然後模式串向右滑動,例如,模式串abcd xxabci x在第i位失配,只需要模式串滑到d與主串繼續比較。哎呀表達得不...