• 字符串算法①——kmp


    kmp算法是用来找A字符串的子串B的出现次数和位置的一种算法;

    在看后面之前先看一个链接https://kb.cnblogs.com/page/176818/

    然后对算法就有个大概的理解

    为了实现这种算法我们需要一个next数组,也就是刚才链接里的部分匹配表,next[i]表示‘B中以i结尾的非前缀子串’与’B的前缀‘能够匹配的最长长度;

    如:abababaac的i=7 为结尾的’非前缀子串‘有6个,分别是2~7,3~7,4~7,....,7~7;

    如B【2~7】=’bababa‘与前缀’ababab'不匹配

       B【 3~7】=‘ababa’与前缀‘ababa'匹配,长度为5;

    .............

    得出next【7】=5;

    但如何求出next数组我们可以假设next【1~6】已经被求出。next【6】=4;及B【3~6】与B【1~4】匹配;

    接下来,B【7】=B【5】=’a',所以B【7】=5;皆大欢喜,下一个匹配了;

    但当next【8】时,B【8】=‘a'   B【6】=’b'不匹配;

    所以我们只好把匹配长度缩短;就是说上面我们以i=7结尾的匹配长度出了5之外,还有B[5~7]于B【1~3】的长度为3的匹配;B【1】于B【7】的长度为1的匹配;

    我们尝试这两种匹配能否使i=8时匹配;

    但B【8】于B【4】,B【2】不相等,所以我们只能让i=8从头开始匹配,B【1】恰好于B【8】匹配;所以next【8】=1;

    单我们是如何记录5,3,1这些匹配长度的?

    首先next【7】=5;说明从i=7往前5个字符于B【1~5】是相等的。

    这是我们定义一个j;使从5往前j个字符与B【1~j】匹配;什么意思,就是以5为next【5】;(别忘了next数组定义);

    当j=next【5】=3之后,下一个要找的就是next【3】;

    所以代码就有了(可能还没有,看看代码就会了)

    1.初始化next【1】=j=0,假设next【1~i-1】都求出,正在求next【i】。
    2.尝试匹配下一位,若果匹配失败,就令j=next【j】(上面讲了为什么)。直到j=03.若果匹配,就令j+1,next【i】=j;
    
    next[1]=0;
    for(int i=2,j=0;i<=strlen(a);++i)
    {
        while(j>0 && a[i]!=a[j+1]) j=next[j]; ////匹配失败
        if(a[i]==a[j+1]) j++;      /// 匹配成功
        next[i]=j;
    }

    然后有了next数组就可以kmp了

    for(int i=1,j=0;i<=strlen(b);++i)
    {
        while(j>0 && (j==n || b[i]!=a[j+1])) j=next[j];
        if(b[i]==a[j+1]) j++;
        if(j==strlen(a)) ///此时匹配  位置为i-strlen(a)+1
    }

    然后就没了;

  • 相关阅读:
    prototype属性
    mui 结束时间不能大于开始时间
    DOM方式操作元素属性
    用户输入数字,自动生成钱值
    isNaN函数,判断其参数是否为数字类型
    switch 循环
    淘宝下单高并发解决方案(转)
    NLog文章系列——如何配置NLog(转)
    使用Nlog记录日志到数据库
    NLog文章系列——如何配置NLog
  • 原文地址:https://www.cnblogs.com/AidenPearce/p/8456005.html
Copyright © 2020-2023  润新知