KMP

用于字符串匹配,复杂度O(n+m)

步骤:

1.b串自我匹配出f数组,其中f[i]表示以b[i]为结尾的后缀与前缀的最大匹配长度-1

2.依次与a串中每个字符匹配。i、j分别作为a与b的指针。

  若a[i]==b[j] 两个指针后移,再判断j是否到达b末

  否则 若j非0 j = 上一个匹配位置f[j-1]+1

    否则 i指针后移(不可能再匹配了)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 char a[1000010],b[1000010];
 8 int f[1000010];
 9 int n,m,ans;
10 
11 int main(){
12     memset(f,-1,sizeof f);
13     scanf("%s%s",a,b);
14     n = strlen(a),m = strlen(b);
15     f[0] = -1;
16     for(int i = 1,j;i < m;i++){
17         j = f[i-1];
18         while(j >= 0&&b[j+1]^b[i])j = f[j];
19         if(b[j+1]^b[i])f[i] = -1;
20         else f[i] = j+1;
21     }
22     for(int i = 0,j = 0;i < n;)
23         if(a[i] == b[j]){
24             ++i,++j;
25             if(j == m){
26                 printf("%d\n",i-m+1);
27                 j = f[j-1]+1;
28             }
29         }
30         else{
31             if(j)j = f[j-1]+1;
32             else i++;
33         }
34     for(int i = 0;i < m;i++)printf("%d ",f[i]+1);
35 return 0;
36 }

 

posted @ 2019-10-31 20:23  TIH_HIT  阅读(117)  评论(0编辑  收藏  举报