zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    The builder launch configuration could not be found
    桌面上的图标不见了
    outlook软件后台运行
    c盘突然少了容量
    win7台式机睡眠时间修改
    系统占用的内存
    详细讲解 java 中的synchronized 转自 http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html
    The US ASCII Character Set 对应码 可以解决 URL中的特殊符号的传输问题
    oracle基本操作 转载
    内存中的 栈与堆
  • 原文地址:https://www.cnblogs.com/Jessica-Cao/p/13547161.html
Copyright © 2011-2022 走看看