zoukankan      html  css  js  c++  java
  • KMP算法

    算法流程

    我们称A串为主串(母串),用来匹配的B串为模式串。

    我们用指针i,j表示A[i-j+1...i]与B[1...j]的值完全相等

    若A[i+1]==b[j+1] i++,j++;

    否则减少j的值来保证A[i],B[j]仍然满足以上关系

    j减少为j' 合法的j'应当满足B[1...j']与B[j-j'+1...j]的值完全相等

    发现j'的取值只与B[j]相关

    所以我们可以预处理出一个p[j]表示匹配到B串的第j个字母而第j+1个字母不能匹配时,最大的j'取多少

    怎么预处理出p[]呢

    假设我们现在已经知道了p[1..i-1]要求p[i]

    若B[i+1]==p[i-1]+1 p[i]=p[i-1]+1

    否则再看B[i+1]是否等于p[p[i-1]]+1 就一直这样子就可以啦

    做题

    HDU2087 剪花布条

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define R register
     5 #define go(i,a,b) for(R int i=a;i<=b;i++)
     6 #define yes(i,a,b) for(R int i=a;i>=b;i--)
     7 #define ll long long
     8 #define db double
     9 using namespace std;
    10 const int N=1005;
    11 char a[N],b[N];
    12 int lena,lenb,ans,p[N];
    13 void init()
    14 {
    15     p[1]=0;
    16     go(i,2,lenb)
    17     {
    18         int c=p[i-1];
    19         while(c&&b[i]!=b[c+1])c=p[c];
    20         if(b[i]==b[c+1])p[i]=c+1;else p[i]=0;
    21     }
    22 }
    23 int main()
    24 {
    25     while(1)
    26     {
    27         cin>>(a+1);if(a[1]=='#')break;
    28         cin>>(b+1);ans=0;
    29         lena=strlen(a+1),lenb=strlen(b+1);
    30         init();
    31         int j=0;
    32         go(i,0,lena)
    33         {
    34             while(j&&a[i+1]!=b[j+1])j=p[j];
    35             if(a[i+1]==b[j+1])j++;
    36             if(j==lenb){ans++;j=0;}
    37         }
    38         printf("%d
    ",ans);
    39     }
    40     return 0;
    41 }
    View Code

    吐槽一下这题数据好水,开始我把init()函数注释掉了都AC了

     POJ2406 Power Strings

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define R register
     5 #define go(i,a,b) for(R int i=a;i<=b;i++)
     6 #define yes(i,a,b) for(R int i=a;i>=b;i--)
     7 #define ll long long
     8 #define db double
     9 using namespace std;
    10 int rd()
    11 {
    12     int x=0,y=1;char c=getchar();
    13     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    14     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    15     return x*y;
    16 }
    17 const int N=1000005;
    18 char a[N];
    19 int p[N],len;
    20 void sol()
    21 {
    22     p[1]=0;
    23     go(i,2,len)
    24     {
    25         int b=p[i-1];
    26         while(b&&a[i]!=a[b+1])b=p[b];
    27         if(a[i]==a[b+1])p[i]=b+1;else p[i]=b;
    28                 //注意else这一步是因为多组数据,p[i]的初始值不一定为0
    29     }
    30 }
    31 int main()
    32 {
    33     while(1)
    34     {
    35         scanf("%s",a+1);if(a[1]=='.')break;
    36         len=strlen(a+1);sol();
    37         if(len%(len-p[len])==0)printf("%d
    ",len/(len-p[len]));
    38         else printf("1
    ");
    39     }
    40     return 0;
    41 }
    42             
    View Code
    光伴随的阴影
  • 相关阅读:
    Java 的this和super关键字
    Java关于访问控制权限
    Java 封装 继承 多态
    Java的集成开发工具
    如何查询小程序中的代码量
    小程序中使用echarts及使用的坑
    微信小程序-新的页面授权机制
    前端处理几十万条数据不卡顿(window.requestAnimationFrame)
    Vs code中Eslint 与 Prettier格式化冲突
    从原型与原型链的角度看es6 class
  • 原文地址:https://www.cnblogs.com/forward777/p/10387212.html
Copyright © 2011-2022 走看看