首页 > 代码库 > 串的模式匹配算法(KMP)

串的模式匹配算法(KMP)

算法:

#include<IOSTREAM>
using namespace std;

#define MAXSIZE 100

void calNext(const char *T,int *next);//T为模式串,next为预判数组
int kmp_match(const char *S,const char *T);//在主串S中寻找模式串T,如果找到返回其位置,否则返回-1。位置从0开始

void calNext(const char *T,int *next)
{
    int n = strlen(T);
    if(n <= 0)
    {
        return;
    }
    int j = 0,k = -1;
    next[0] = -1;
    while(j < n)
    {
        if(k==-1 || T[j]==T[k])
        {
            j++;
            k++;
            next[j] = k;
        }else
        {
            k = next[k];
        }
    }
}
int kmp_match(const char *S,const char *T)
{
    if(S==NULL || T==NULL)
    {
        return -1;
    }
    int n = strlen(S);//主串长度
    int m = strlen(T);//模式串长度

    int next[MAXSIZE];
    calNext(T,next);

    int i = 0,j = 0;
    while(i+m <= n)
    {
        for(;i<n&&j<m&&S[i]==T[j];++i,++j);
        if(j==m)
            return i-m;
        j = next[j];
        if(j==-1)
        {
            j++;
            i++;
        }
    }
    return -1;
}

注:
原理:利用已经部分匹配这个有效信息,保持i指针不回溯,通过修改j指针,让模式串尽量地移动到有效的位置,有效位置即为所谓的next数组。
next数组计算过程:
声明next数组下标从0开始,定义next[0]=-1;模式串为T[]
假如求T中j+1位的next[j+1]
将其前一位的内容与其前一位的next值(next[j])的内容(T[next[j]])进行比较;
如果他们相等(T[j]==T[next[j]]),则next[j+1]=next[j]+1;
如果他们不相等,则继续向前比较,直到找到next值对应的内容与前一位相等为止,则在这个next值上加1;
如果直到第一位都没有与之相等,则next[j+1]=0