• KMP


    作用是找大串里匹配的小串的位置

    理解好难,先讲一下原理。找目前字符串的Border:是一个字符串最长的,能跟真后缀相同的真前缀的长度。

    比如ABCDABCD

    从1号到八号 Border分别是00001234.。

    如何求Border:

    我们以ABABAC为例

    用肉眼明显知道

    001230

    我们知道如果前面的字符串对称,只需要把当前字符和前面字符对称总数+1比较,如果继续对称,那么对称总数+1,否则

    我们回到F[前一个总对称数]+1,这个字符比较,如果相等,下次比较则比较这个字符串的下一个即刻,如果依然不等,继续上述操作直到起点。

    感觉没讲得很清楚,看了一位大佬的博客,理解了一点,结合学长的代码,模拟了一下。

    https://blog.csdn.net/u011564456/article/details/20862555

    大佬链接。

    求出了Border.。我们需要利用Border进行优化匹配。

    还是刚才那个道理,匹配字符看Boeder,即看是否有无效的匹配。

    ABCBABCAAB

    ABCAA

    匹配到第4个就无法匹配了,我们此时可以利用Boeder,直接移动三位而不是一位。

    从而产生优化的效果。

    例如:

    学长的例子

    P=ABCDABD

    T=ABCABCDABABCDABCDABDE

    T的第一个位置开始匹配

     

    123456789012345678901

    ABCABCDABABCDABCDABDE

    ABCDABD

    1234567

     

    P的第4个字符匹配失败!

    我们到此成功匹配到了P3个字符,而F[3]=0

    - 所以也无法在??T_2, ?? T_3处继续产生匹配;

    P串向右移动k-F[k]=3个字符

     

    123456789012345678901

    ABCABCDABABCDABCDABDE

    ABCDABD

    1234567

    我们到此成功匹配到了P3个字符,而F[3]=0

    - 所以也无法在??T_2, ?? T_3处继续产生匹配;

    P串向右移动k-F[k]=3个字符

     

    123456789012345678901

    ABCABCDABABCDABCDABDE

                           ABCDABD

     1234567

    此时我们需要移动4而不是6.

    我们可以知道F[6]=2;

    即移动k-F[k]=4;

     

     

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1000050;
    int F[maxn];
    char P[maxn],T[maxn];
    void getF(char *P,int m) {
        F[1]=0;
        for(int i = 2; i <= m; ++i) {
            int k=F[i-1];
            while(k&&P[k+1]!=P[i]) k=F[k];
            if(P[k+1]==P[i]) ++k;
            F[i]=k;
        }
    }
    void getMatch(char *P,int m,char *T,int n)
    {
        getF(P,m);
        int k=0;
        for(int i = 1; i <= n; ++i) {
            while(k&&T[i]!=P[k+1]) k=F[k];
            if(T[i]==P[k+1]) ++k;
            if(k==m) {
                printf("matched at %d
    ", i-m+1);
                k=F[k];
            }
        }
    }
    int main() {
        scanf("%s%s", T+1,P+1);
        getMatch(P,strlen(P+1),T,strlen(T+1));
        return 0;
    }
    
    

    学长的代码。镇楼。

  • 相关阅读:
    SQl 事物+视图+游标+索引+锁
    常用经典SQL语句大全完整版--详解+实例 《来自网络,很全没整理,寄存与此》
    SQL--存储过程+触发器 对比!
    SQL---触发器
    SQL (一)定义变量以及变量赋值
    Js 事件大全
    ASP.NET 常用内置对象详解-----Response
    母板页----路径问题
    构建低代码开发生态,APICloud全面进入3.0时代
    APICloud:云端服务开发的硬核要素
  • 原文地址:https://www.cnblogs.com/skyleafcoder/p/12319561.html
Copyright © 2020-2023  润新知