算法导论(九)kmp匹配算法

本文详细介绍KMP算法原理及其应用,通过实例演示如何高效地在文本中查找模式串,避免重复比较,实现O(n)时间复杂度。

算法导论第32章

题目:pku1961, pku2406, pku2752

首先举个例子:要在一个字符串中找到和ababaca匹配的字符串的个数.

b a c b a b a b a a b c b a b

            a b a b aca

在这里前面有5个已经匹配成功,第六个不成功.

通过观察可以知道,并不需要往后面移动一个位置继续比较,实际上可以直接移动两个位置比较.

a b a b a c a

      a b a b a c a 

如果移动一个位置,可以看到a,b不相等,再移动一个位置,把前面三个相等的比较下,再比较第四个,当然这就多出了很多时间,也做了很多不必要的工作.

可以通过先计算出前缀函数,就不必做多余的计算了.这样就达么了O(n)的时间复杂度.

void kmp_matcher(char *T, char *P)
{
    n = length(T);
    m = length(P);
    @ = compute_prefix_function(P);
    q = 0;
    for (int i = 1; i < n; i++)
    {
        while (q > 0 && P[q+1] != T[i])
            q = @[q];
        if (P[q+1] == T[i])
            q = q+1;
        if (q == m)
        {
            cout << "find one";
            q = @[q];
        }
    }
}

char *compute_prefix_function(char* P)
{
    m = length[P];
    @[1] = 0;
    k = 0;
    for (q = 2; q < m; q++)
    {
        while (k > 0 && P[k+1] != P[n])
        {
            k = @[k];
        }
        if (P[k+1] == P[q])
            k = k+1;
        @[q] = k;
    }
    return @;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值