Kmp演算法學習筆記

2021-06-22 06:10:22 字數 1662 閱讀 5517

kmp演算法我認為難點在next陣列的建立。 看kmp前我仔細看了下傳統的匹配模式,**為:(首元素存放串的長度)

int index(sstring s,sstring t)

else

i = i-j+2;

}if(j > t[0])

return i-t[0];

else 

return 0;

}我認為想深刻理解好kmp演算法要和傳統匹配匹配結合起來。kmp無非就是利用next陣列的資訊,即最長字首子串的長度來令j的值回溯,而不是像傳統匹配那樣令i的值回溯。

int index_kmp(sstring s,sstring t)

else

j = next[j];}

if(j > t[0])

return i-t[0];

else 

return 0;

}kmp最主要的就是next陣列的建立,這也是kmp的難點,也是困擾了我很久的地方。

先敲遍next陣列的函式以找回感覺:

void get_next(char *t,int *next)

else   //當 j != 0 && t[i] != t[j] 時,既然當前字元不相等了,那就令j回溯到可能相等的位置再匹配,記住,是可能相等。若再不相等則再回溯,直至j回溯到盡頭

j = next[j];   //此步是令j回溯,可以將next陣列的建立看為從第i個字元開始的串t,與從第j個字元開始的串t 匹配。}

if(j > t[0])

return i - t[0];

else

return 0;

}其實還有一點就是因為這裡運用的串的資料結構t[0]或s[0]的存放的是串的長度,且串的起始下標是從i開始的,而平時用字串的話我用的都是從0開始的,且長度是直接用字串函式strlen()計算出來。若用資料結構,則上述的**就有了一點改變,但總體結構還是一樣的,我是比較完兩者的差別,然後才學會了kmp的。

下面貼出普通型別字串的kmp演算法(紅色字型為有一些值得注意的細節改變):

int index_kmp(char *s,char *t)   //字串s和t的下標都是從0開始

else

j = next[j];

}if(j == len2)

return  i-j;

else 

return -1;   //下標從0開始,所以不能return 0  }

void get_next(char *t,int *next)

else

j = next[j];}}

若串的下標是從1開始的,那麼next陣列的值分別為 next[1...n] =      0,1,1,2,3,4,2,2,3

若串的下標是從0開始的,那麼next數則的值分別為 next[0...n-1] = -1,0,0,1,2,3,1,1,2 

以上是我自學kmp時的一些心得體會和方法,當時kmp演算法困了我很久,而且一旦長時間不用就容易忘記,所以寫篇部落格來加深印象,也有利於以後的複習。

我知道自己有些地方寫的不是那麼正確,希望看見的朋友能夠指出並共同**,我也只是乙個剛學資料結構的菜鳥。這也是我csdn上的**部落格,若真有看不過眼的地方請不要噴我,很打擊自信的...  更希望能在csdn上認識更多志同道合的朋友一起學習,**問題!

KMP演算法學習筆記

kmp是一種字串匹配演算法,網上有許多的講解和介紹,都非常清楚明白,這裡只說明一點next i 表示 1,i 1 位中的最長公共字首字尾,因此在遇到字元不匹配時,直接將字串右移j next j 位即可。不多說了,直接上習題 poj 3461 oulipo kmp演算法裸題,直接上模板 code in...

KMP演算法學習筆記

前幾天學習了關於字串處理的kmp演算法,剛學的時候沒怎麼懂,通過今天的練題,終於把kmp掌握了。kmp演算法利用了字串的一些特殊性質,通過字首陣列,將單個字串的匹配問題由o m n 優化到了o m n 這裡,我存幾段關鍵性 首先是get next 函式 void get next 然後是kmp vo...

KMP演算法 學習筆記

一種字串的快速匹配演算法 舉個栗子 找s2在s1中出現的位置 正常的做法 先從第乙個位置開始匹配,匹配到s2的最後一位時,發現不同,這時,把s2右移一位,再從頭開始匹配,如圖 如此匹配下去,直到 但是,我們可以看出,前面的三次匹配都是多餘的,我們可不可以直接跳到這一步呢?kmp演算法 我們一開始是匹...