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];
    }
    }
  • 相关阅读:
    office(PPT、Word、Excel)功能目录
    《数商》笔记
    笔记模板
    如何运用思维导图安排考生读书计划(增订版)
    自制桌面图片
    selenium+AutoIt
    selenium中应用问题解决
    mysql卸载
    vue每次修改刷新当前子组件
    vue与dajngo
  • 原文地址:https://www.cnblogs.com/planche/p/9384006.html
Copyright © 2011-2022 走看看