zoukankan      html  css  js  c++  java
  • KMP模式串匹配

     查询在一个很长n的“文本串”中,给定的很短m的“模式串”的出现有无,次数,位置

    复杂度O(n+m) 而不是暴力的O(n*m)
    这里对模式串做了一个神奇的移位法则,注意KMP是只针对模式串的操作,不是文本串
    我喜欢把kmp叫做“对应的前一项前缀位置”
    例如:
    KMP记录的是怎么一回事,看图看数据马上就明白了
    123123123923123123 ----模式串
    000123456000123456 ----对应KMP数组值


    还有点模糊?
    再来组数据
    1231212312
    0001212345


    根据这两张图总结下:
    1.由图二可知,匹配基数为字符串的所有前缀(12,123均为前缀)
    2.由图一二对比发现,如果字符串出现与前缀中断匹配的部分,或者自己本身就是前缀的话,那么这些部分的KMP值全部为0
    3.如果字符串与前缀匹配一直没有发生中断,那么当前位置KMP值可以承接为离自己最近的前缀KMP值

    上代码:

    char str[N];
    cin>>str+1;
    int j=0;
    int len=strlen(str+1);
    For(i,2,len){
    while(j&&str[i]!=str[j+1]) j=kmp[j]; //若发现自己后面的点无法匹配,那就跳为kmp值(前一个前缀值)
    if(str[i]==str[j+1]) j++;//直到有东西开始和前缀发生匹配
    kmp[i]=j;//承接前一个前缀配对的位置或是指向0
    }

    接下来直接和文本串匹配其实跟模式串内部匹配没有实质区别:

    char text[N];
    cin>>text+1;
    j=0;
    for(int i=1;i<=strlen(text+1);i++)
    {
    while(j>0&&str[j+1]!=text[i])
    j=kmp[j];
    if (str[j+1]==text[i]) 
    j++;
    if (j==len) { //长度符合就输出
    cout<<i-len+1<<endl;
    j=kmp[j];
    }
    }
  • 相关阅读:
    Linux下安装Flume
    [译]MIT6.824_1.1分布式系统介绍——驱动力与挑战
    MySQL-Canal-Kafka数据复制详解
    Linux下搭建Kafka集群
    我在创业公司的云原生之旅
    使用go向es进行数据操作脚本
    kubectl exec 向pod的文件中增加内容
    kubernetes资源导出小脚本
    面试题(四) -- 第一次当面试官
    gitlab备份检查小脚本
  • 原文地址:https://www.cnblogs.com/planche/p/9384006.html
Copyright © 2011-2022 走看看