1. 程式人生 > >KMP的理解與模板

KMP的理解與模板

。。 p s -- https != 修改 我們 找到 cnblogs

                  KMP

T串主串 P串模式串

i

T串:A B C A B C D H I J K

P串: A B C E

j

保持i指針不回溯,通過修改j指針,讓模式串盡量地移動到有效的位置

接下來我們自己來發現j的移動規律:

技術分享圖片

如圖:CD不匹配了,我們要把j移動到哪?顯然是第1位。為什麽?因為前面有一個A相同啊:

技術分享圖片

如下圖也是一樣的情況:

技術分享圖片

可以把j指針移動到第2位,因為前面有兩個字母是一樣的:

技術分享圖片

當匹配失敗時,j要移動到下一個位置k。(模式串)存在著這樣的性質:最前面的k個字符和j之前的最後k個字符是一樣的。

P[0~k-1] ==P[j-k~j-1]

比如: a b c d a b c
i == : 0 1 2 3 4 5 6 7
next:-1 0 0 0 0 1 2 3

void get_next() //初始化next數組 lenpp數組的長度

{

int i,j;

Next[0] = j = -1;

i = 0;

while(i<lenp) //最後一位的判斷其實是多余的

{

while(j!=-1&&p[j]!=p[i])

j = Next[j];

Next[++i] = ++j;

}

}

-----------------------------------------------------------------------------------------------------------------------

Kmp部分:

i0 1 2 3 4 5 6 7 8 9

T串: a b c e a b p a b c

P串: a b c d a b c

Next[]-1 0 0 0 0 1 2

i=3處,j= 3 t[i]!=p[j],j的指針返回到next[3] j = 0

i0 1 2 3 4 5 6 7 8 9

T串: a b c d a b p a b c

P串: a b c d a b c

Next[]-1 0 0 0 0 1 2

若一直匹配至i=6

j= 6t[i]!=p[j],j返回到next[6] 移動j指針 即j=2

int kmp1() //t串找p串 返回下標

{

int i,j;

i = j = 0; //兩個下標指針 i為主串的指針 j為模式串的指針

while(i<lent&&j<lenp)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

i++;

j++;

}

if(j==lenp)

return i-j; //若找到返回開始下標(從0開始)

return -1; //找不到返回-1

}

t[] aaaaaa

p[] aa

返回的ans = 5

int kmp2() //返回匹配次數

{

int i,j;

i = j = 0;

int ans = 0;

while(i<lent)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

if(j==lenp-1)

{

ans++;

j = Next[j];

}

i++;

j++;

}

return ans;

}

t[] aaaaaaa

p[] aaa

返回的ans = 2

int kmp3() //返回t串中有多少個p

{

int i,j;

i = j = 0;

int ans = 0;

while(i<lent)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

if(j==lenp-1)

{

ans++;

j = -1; // j指針改變為-1 然後++ 0重新查找

}

i++;

j++;

}

return ans;

}

@一些KMP的模板題目(用上面的模板做的)

剪花布條 https://www.cnblogs.com/hao-tian/p/9643905.html (用到了模板中的kmp3函數)

學習中。。有錯誤請指正 謝謝

KMP的理解與模板