1.KMP算法
这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html
模板:
next数组的求解,那个循环本质就是如果相同前后缀不能加上该位置成就该位置的next数组就一直找相同前后缀的相同前后缀。
求解前缀数组F(也叫next数组):
for (int i=1;i<m;i++) { int j=F[i-1]; while ((B[j+1]!=B[i])&&(j>=0)) j=F[j]; if (B[j+1]==B[i]) F[i]=j+1; else F[i]=-1; }
利用F数组寻找匹配,这里我们是每找到一个匹配就输出其开始的位置:
while (i<n) { if (A[i]==B[j]) { i++; j++; if (j==m) { printf("%d\n",i-m+1); j=F[j-1]+1; } } else { if (j==0) i++; else j=F[j-1]+1; } }
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset((a),(b),sizeof(a)) const int N=1e3+5; int f[N]={-1}; char a[N*N]; char b[N]; int main() { /*ios::sync_with_stdio(false); cin.tie(0);*/ scanf("%s",a); scanf("%s",b); int m=strlen(b); int n=strlen(a); for(int i=1;i<m;i++) { int j=f[i-1]; while(b[j+1]!=b[i]&&j>=0)j=f[j]; if(b[j+1]==b[i])f[i]=j+1; else f[i]=-1; } int i=0,j=0; while(i<n) { if(a[i]==b[j]) { i++; j++; if(j==m) { printf("%d\n",i-m+1); j=f[j-1]+1; } } else { if(j==0)i++; else j=f[j-1]+1; } } for(int i=0;i<m;i++) { printf("%d",f[i]+1); if(i!=m-1)printf(" "); else printf("\n"); } return 0; }