關於KMP算法的個人理解

#include<stdio.h>
#include<string.h>
#define N 100
typedef struct Strings
//定義結構體包含string字符串和length長度屬性 
{
    char string[100];
    int length;
} sq;

//GetNext裏面是關於next數組的 
void GetNext(sq q,int next[])
{
    int i=0;
    int j=-1;
    next[0]=-1;
    while(i<q.length)
//匹配上限約束,小於傳入的長度 
    {
        if(j==-1||q.string[i]==q.string[j])
        //當j=-1時,爲第一個,不需要匹配跳過分別ij++;進行下一個的匹配
		//自匹配,ij匹配相同則進行下一個匹配,若相同,此時next[i]就是當前最大匹配前後綴,就是j=i-1; 
        {
            i++;
            j++;
            next[i]=j;

        }
        else
        {
        	//如果自匹配失敗,說明,當前string[i],string[j]的值不一致,則i前一個的爲next[j],是當前滿足的最大的匹配前後綴
			//此時,需要後移,而有個最大匹配前後綴的長度不需要再進行比較,在這一步可以賦給j,達到向右移動的目的;就是跳過前面的最大匹配量 
            j=next[j];
        }
        for(i=0; i<q.length; i++)
        {

            printf("%2d",next[i]);
        }

    }

}
int Kmp(sq s,sq p,int next[])
//傳入三個參數,兩個結構體字符串 
{
    int c=0;
    int d=0;
    while(c<s.length&&d<p.length)
 //最大長度約束 
    {
        if(d==-1||s.string[c]==p.string[d])
       //當前匹配成功則加一匹配下一項 
		{
        	

            c++;
            d++;
        }
        else
        {
        	//若匹配失敗,則獲取當前的next[],即最大的相同前後綴的長度,將d實現移動,若next[d]=0;進行下一輪時可能會發生繼續匹配失敗
			//此時的d=next[0]=-1;就是第一個字符;所以考慮這種情況時,同樣++; 
            d=next[d];
        }

    }
    if(d==p.length)
//成功,因爲s,p相同時才++:不同的時候next[d]肯定小於d;當d能達到p.length時說明已經有成功的完成匹配了 
        return c-p.length;
    else
        return -1;
        //失敗 


}


int main (void)
{
    int next[N];
    int a;
    sq s;
    sq p;
    printf("Please input S string :\n");
    scanf("%s",s.string);
    printf("Please input p string :\n");
    scanf("%s",p.string);
    s.length=strlen(s.string);
    p.length=strlen(p.string);
    GetNext(p,next);
    printf("\n");
    if(Kmp(s,p,next)!=-1)
    {
        printf("KMP匹配成功\n");
        for(a=Kmp(s,p,next); a<Kmp(s,p,next)+p.length; a++)
        {
        	
        	//kmp不爲-1時返回的是c-p.length,所以a=c-p.lenght,a<c;a++ 
            printf("%c",s.string[a]);
         
		}
        

    }
    else
    {
        printf("失敗\n");

    }

    return 0;

}

難點在於next數組如何設計,自匹配,和兩個之間的匹配,需要考慮最大相同前後綴來提高效率,個人理解尚淺薄,只能get到優化的點,具體實現邏輯未弄懂。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章