• KMP


    推荐blog:

    https://www.luogu.com.cn/blog/pks-LOVING/zi-fu-chuan-xue-xi-bi-ji-qian-xi-kmp-xuan-xue-di-dan-mu-shi-chuan-pi-post

    http://www.matrix67.com/blog/archives/115(先看这些blog)

    首先,普通字符串匹配是一个一个进行匹配,配不上了,就将整个字符串往后挪一位,再从头开始匹配,大概就像这样:

    但这样的时间复杂度为O(nm);

    而KMP这不一样,下面我来演示以下:

    大概是这样的两个串

    接下来进行匹配

    比如粉色代表匹配成功,但在下一位匹配时却匹配失败了,按照普通的搞法,应该是将b往后挪一位,咱们从头再来,但kMP却是这样的:

    我们发现标蓝的部分相同(当前匹配位置的后缀与前缀相同的最长部分),那么,我们可以直接将b蓝色的前一部分,挪到后一部分蓝色,就像这样

    然后继续往后进行匹配,反复这些操作,直至找到一次完全匹配,然后再继续匹配

    如何迅速找到当前位置border的最大长度呢(注:border就是一个串前缀和后缀相等部分的最大长度)

    可以自己先跟自己匹配,用一个数组next[i]来表示位置i的boder的长度

    自己怎么跟自己匹配?自己跟自己不是一样的吗?(迷惑)

    没有关系,既然知道自己跟自己匹配时从第一位开始匹配是一样的,那用自己的第二位与自己的第一位开始匹配就可以了

    推荐题:洛谷P3375

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int kmp[1000006];
     4 char a[1000006],b[1000006];
     5 int main(){
     6     int lena,lenb,i,j;
     7     cin>>a+1>>b+1;
     8     lena=strlen(a+1);lenb=strlen(b+1);
     9     j=0;
    10     for(i=2;i<=lenb;i++){
    11         while(j&&b[j+1]!=b[i])j=kmp[j];
    12         if(b[j+1]==b[i])j++;
    13         kmp[i]=j;
    14     }j=0;
    15     for(i=1;i<=lena;i++){
    16         while(j&&b[j+1]!=a[i])j=kmp[j];
    17         if(b[j+1]==a[i])j++;
    18         if(j==lenb){
    19             cout<<i-lenb+1<<endl;
    20             j=kmp[j];
    21         }
    22     }
    23     for(i=1;i<=lenb;i++)cout<<kmp[i]<<" ";
    24     return 0;
    25 }
  • 相关阅读:
    通过Powershell开启RDP
    映射网络驱动器
    简易图书管理系统
    使用IDEA快速创建Spring Boot项目
    oracle11g安装步骤详细图文教程
    使用JDOM创建XML文档
    使用JDOM解析XML文档
    HTML+CSS之金立官网部分实现
    webstorm2019安装与使用详细教程
    第二章 JavaScript基础指令
  • 原文地址:https://www.cnblogs.com/Jessica-Cao/p/13547161.html
Copyright © 2020-2023  润新知