详解KMP算法

普通的匹配算法在最坏的情况下的效率很低,如:‘00001’,主串:‘00000000000000001’,则时间复杂度为O(n*m ).
kmp算法不需要回溯指针,KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
简单来说,模式串中的某个字符匹配失败了,返回下一个要查找的字符,看个例子:模式串:‘abcabd’,主串:‘cabcabcabd’,第一次匹配模式串的第一个与主串的第一个不匹配,则指针向后移动一位,模式串的第一个与主串的第二个匹配成功,依次向后匹配,当模式串的最后一个字符‘d’与主串的第5个字符‘c’匹配失败这时不需要指针回溯,观察主串与模式串发现将模式串的第三歌字符与刚刚主串中匹配失败的字符匹配,这便是kmp算法的核心思想。
还可以多举几个例子,便可以发现:
移动位数 = 已匹配的字符数 - 对应的部分匹配值
那我们只需要将模式串中的各个字符匹配失败是移动的位数求出,用一个数组存放,取名next。

typedef char String[MAX + 1];//0位贮存串的长度

定义了一个串的类型。下面是的得到next数组的函数

void getNext(int *next,String str)
{
    int i = 0,j = 0;
    int length = str[0];
    next[0] = 0;
    while(i < length)
    {
        if(!j || (str[i] == str[j]))
        {
            j++;
            i++;
            next[i] = j;
        }
        else
            j = next[j];
    }
}

求得了next数组就可以进行匹配算法

int match(String str1,String str2)
{
    int next[str1[0] + 1],i = 0,j = 0;
    getNext(next,str1);
    while((i <= str1[0]) && (j <= str2[0]))
    {
        if(!i || (str1[i] == str2[j]))
        {
            i++;
            j++;
        }
        else
            i = next[i];
    }
    if(i == str1[0] + 1)
        return j - str1[0];//匹配成功,返回的一个字符的位置
    return 0;
}

当使用kmp算法时时间复杂度为O(m + n)
当然还可以对next数组进行优化,这里不详细写了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值