关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 算法设计 »kmp算法实现原理及简单示例

    kmp算法实现原理及简单示例

    2014-09-18 00:00:00 出处:天地玄黄
    分享

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货。最近有空,翻出来算法导论看看,原来就是这么简单(下不说程序实现,思想很简单)。

    模式匹配的经典应用:从一个字符串中找到模式字串的位置。如“abcdef”中“cde”出现在原串第三个位置。从基础看起

    朴素的模式匹配算法

    A:abcdefg B:cde

    首先B从A的第一位开始比较,B++==A++,假如全部成立,返回即可;假如不成立,跳出,从A的第二位开始比较,以此类推。

    /*
     *侯凯,2014-9-16
     *功能:模式匹配
     */
    #include<iostream>
    #include <string>
    using namespace std;
    
    int index(char *a,char *b)
    {
        int tarindex = 0;
        while(a[tarindex]!='')
        {
            int tarlen = tarindex;
            int patlen;
            for(patlen=0;b[patlen]!='';patlen++)
            {
                if(a[tarlen++]!=b[patlen])
                {
                    break;
                }
            }
            if(b[patlen]=='')
            {
                return tarindex;
            }
            tarindex++;
        }
        return -1;
    }
    int main()
    {
        char *a = "abcdef";
        char *b = "cdf";
        cout<<index(a,b)<<endl;
          system("Pause");
    }

    思路朴实无华,十分有效,但是时间复杂度是O(mn),m、n分别是字符串和模式串的长度。模式匹配是一个常见的应用问题,用的广了,就有人想法去优化了。Rabin-Karp算法、有限自动机等等,前仆后继,最终出现了KMP(Knuth-Morris-Pratt)算法。

    kmp算法

    image

    优化的地方:假如我们知道模式中a和后面的是不相等的,那么第一次比较后,发现后面的的4个字符均对应相等,可见a下次匹配的位置可以直接定位到f了。说明主串对应位置i的回溯是不必要的。这是kmp最基本最关键的思想和目标。

    再比如:

    image

    由于abc 与后面的abc相等,可以直接得到红色的部分。而且根据前一次比较的结果,abc就不需要比较了,现在只需从f-a处开始比较即可。说明主串对应位置i的回溯是不必要的。要变化的是模式串中j的位置(j不一定是从1开始的,比如第二个例子)

    j的变化取决于模式串的前后缀的相似度,例2中abc和abc(靠近x的),前缀为abc,j=4开始执行。

    j是前一次执行的模式子串(前几个,上例为6)中前缀的个数+1;它与模式字串中从前向后的前缀和从后向前的后缀的相同子串是有关系的,因为下次这部分相同的前缀就会移动到这部分后缀的位置,因为假如移动到后缀的前面位置,看图:

    image

    所以假如这次是j,下次的位置应该就是j前面的子串的最大前缀的长度+1,用这个新的位置再和原字符串的i位置进行比较就很幸福了。

    这次是j,下次到底是多少呢,这就涉及到怎么计算的问题了?其实只看模式串我们就可以构建出这个j->x的关系,关系称为前缀函数,结果存储在数组中,称为前缀数组。

    伪代码:

    compiter-prefix-function(P)
        m<-length[p]
        pi[1]<-0
        k<-0
        for q<-2 to m
            do while k>0 and P[k+1]!=P[q]
                        do k<-pi[k] //前缀的前缀...
               if P[k+1]==P[q]
                        then k<-k+1
               pi[q]<-k
        return pi

    使用前缀数组可很快地实现模式匹配,程序匹配字符串中模式出现的所有位置。

    kmp-matcher(T, P)
        n<-length[T]
        m<-length[P]
        pi<-compiter-prefix-function(P)
        q<-0
        for i<-1 to n
            do while q>0 and P[q+1]!=T[i]
                do q<-pi[q] //前缀的前缀...
            if P[q+1]==T[i]
                then q<-q+1
            if q==m
                then print “Pattern occurs with shift”i-m
                        q<-pi[q]

    这两段代码思想完全相同,假如和前缀不同就比较前缀的前缀…,比较巧妙。假如kmp有难理解的地方,估计就是这段伪码的了。

    KMP算法的时间复杂度为O(n+m)。

    这里需要强调一下,KMP算法的仅当模式与主串之间存在很多部分匹配情况下才能体现它的优势,部分匹配时KMP的i不需要回溯,否则和朴素模式匹配没有什么差别。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。