KMP算法-找出模式串匹配標準串的第一個位置

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’的位置,我們減去子串的長度,就是子串第一次出現的位置

我們可以發現當子串與標準串不同的時候(我們記當前標準串的字母爲arr[index] );子串會整體移動;移動到子串從後往前看,子串第一次和arr[index]相等的位置。 我們會發現移動後的子串還是會和標準串相匹配。next表工作就是這個 這需要讀者自己理解一下。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章