KMP算法-找出字串出現的第一個位置
我們先得出子串(也就是標準串的NEXT[]表的值。上講已經講過如何算出給定子串的NEXT[]表的值,此講不再冗述。
第一步給出算NEXT[]表值的算法
arr[]爲題目給出的標準串,brr[]是給定要尋找位置的子串。
next[]是我們新開闢的數組爲空,等待我們算出值放入。
void GETNEXT(char brr[], char next[])
{
int j=0, k=-1;
next[0] = -1;
while(j < strlen(brr)-1)
{
if(brr[j]==brr[k] || k==-1)
{
j++;
k++;
next[j] = k;
}
else k = next[k];
}
}
第二步開始找
先給出代碼
arr[]爲題目給出的標準串,brr[]是給定要尋找位置的子串。
next[]是我們新開闢的數組爲空,等待我們算出值放入。
char next[];
int KMPIndex(char arr[], char brr[])
{
GETNEXT(brr, next);
int i=0, j=0;
while(i < strlen(arr) && j < strlen(brr) //當標準串沒有掃完,並且模式串也沒有掃完
{
if(j==-1 || arr[i)==brr[j])
{
i++;
j++;
}
else j = next[j];
}
//兩方若有一方先掃完,或都掃完
if(j >= strlen(brr)//匹配成功
return i-strlen(brr);
else return -1;
}
給大家舉個栗子
給定標準串 a a a a b
給定模式串 a a a b
顯然模式串的NEXT[]表的值爲
j | 0 | 1 | 2 | 3 |
---|---|---|---|---|
brr [ ] | a | a | a | b |
next [ ] | -1 | 0 | 1 | 2 |
i=0, j=0時
‘a’ = ‘a’
arr[0] == brr[0] ,所以i++, j++
i=1, j=1時
‘a’ = ‘a’
arr[1] == brr[1] , 所以i++, j++
i=2, j=2時
‘a’ = ‘a’
arr[2] == brr[2] , 所以i++, j++
i=3, j=3時
‘a’ != ‘b’
所以 j=next[j]=next[3]=2; i不變
i=3, j=2時
‘a’ = ‘a’
arr[3] == brr[2] , 所以i++, j++
i=4, j=3時
‘b’ = ‘b’
arr[4] == brr[3] , 所以i++, j++
因爲i >= strlen(arr),循環結束
並且j >= strlen(brr) 說明找到啦
返回子串第一次出現的位置 i-strlen(brr)
就是現在 i 代表的位置是標準串中‘b’的位置,我們減去子串的長度,就是子串第一次出現的位置