KMP算法详解

作者: zealscott | 来源:发表于2018-04-17 10:01 被阅读0次


在数据结构课上老师讲了kmp算法,但当时并没太懂,现在把思路重新理一遍。

1.kmp算法简介

KMP是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同时发现的。
KMP算法其实就是一种改进的字符串匹配算法,关键是利用匹配后失败的信息,尽量减少模式串(W)与主串(T)的匹配次数以达到快速匹配的目的。具体实现就是实现一个next() 函数,函数本身包含了模式串的局部匹配信息。时间复杂度 O(m+n)
如果考虑最笨的方法,我们可以将T[0]和W[0]进行匹配,如果相同则匹配下一个字符,直到出现不相同的情况,此时我们会丢弃前面的匹配信息,然后把T[1]跟W[0]匹配,循环进行,直到主串结束,或者出现匹配成功的情况。这种丢弃前面的匹配信息的方法,时间复杂度为O(mn)
KMP算法利用已经部分匹配这个有效信息,保持i指针(主串)不回溯,通过修改j指针,让模式串尽量地移动到有效的位置,具体可见下面一个例子。
如果主串为:a b c a b c d h i j k
模式串为:a b c e
当我们匹配到主串的第四个字符a时,可知a和e不相等,因此需要移向下一位,但其实我们并不需要从模式串中的第一位重新开始比较,因为主串中的前三个字符已经没有未匹配的a了,不可能匹配成功。
[站外图片上传中...(image-f5d3d1-1518266644982)]

2.next()函数

因此,最关键的是找到如何移动j指针。我们记当匹配失败时,j要移动的下一个位置为k(即next[j]= k)。记P为模式串。
很显然,存在这样一个性质:最前面的k个位置(对于模式串来说)和j之前的最后k个字符(主串)是一样的。因此得到公式:

P[0 ~ k-1] == P[j-k ~ j-1]

当P[k] == p[j]时

有P[0 ~ k-1] + P[k] == p[j-k ~ j-1] + P[j],即:P[0 ~ k] == P[j-k ~ j],因此可得

next[j+1] == k + 1 == next[j] + 1

当P[k] != p[j]时

我们只能在0~k-1中去寻找最长后缀串了,因此为

k = next[k]

使用C++ 实现next函数为

    int* getNext(string p)
    {
        int* next = new int[p.length()];
        next[0] = -1;           //while the first char not match, i++,j++
        int j = 0;
        int k = -1;
        while (j < (int)p.length() - 1)
        {
            if (k == -1 || p[j] == p[k])
            {
                j++;
                k++;
                next[j] = k;
            }
            else
            {
                k = next[k];
            }
        }
        return next;
    }

3.完整算法

    int KMP(string T,string p)
    {
        int i=0;
        int j=0;
        int* next=getNext(T);
        while (i < (int)T.length() && j < (int)p.length())
        {
            if (j == -1 || T[i] == p[j])
            {
                i++;
                j++;
            }
            else
            {
                j=next[j];
            }
        }
        if (j == (int)p.length())
        {
            return i-j;
        }
        return -1;
    }

相关文章

  • (转)KMP

    (原创)详解KMP算法

  • 给小白讲解KMP算法

    >> KMP算法详解,小白都懂的讲解,欢迎交流,边听歌边看吧 概念解释 Knuth-Morris-Pratt算法,...

  • KMP算法详解

    在数据结构课上老师讲了kmp算法,但当时并没太懂,现在把思路重新理一遍。 1.kmp算法简介 KMP是三位大牛:D...

  • KMP算法详解

    详解:https://www.cnblogs.com/yjiyjige/p/3263858.htmlhttps:/...

  • Kmp算法详解

    先说一下为啥要了解kmp算法,因为阿里面试有道面试题目,如果在所有字符串最快速度找出目标字符串的位置。我用了最...

  • KMP算法详解

    KMP是解决两个字符串匹配问题的非常好的算法,算法的时间复杂是O(n)。 现在假设场景是两个字符串str1,str...

  • KMP算法详解

    原链接:KMP算法详解|CloudWong 传统的字符串匹配模式(暴力循环) 子串的定位操作通常称作串的串的匹配模...

  • KMP算法详解

    概述 KMP是字符串匹配的经典算法。其中包含的思想,是非常有趣的。本文作为KMP算法的介绍和备忘录。 场景 KMP...

  • KMP算法:详解

    匹配 很简单,用next[x]表示前移数组。 next[i]的生成 匹配过程事实上非常简单,难的是next[x]的...

  • KMP算法详解

    KMP算法是解决字符串匹配的常用算法之一,也就是在主串(比如aabbccdd)中的子串(bc)定位问题。子串称为P...

网友评论

    本文标题:KMP算法详解

    本文链接:https://www.haomeiwen.com/subject/urehtftx.html