『一本通』KMP算法

剪花布条

#include<bits/stdc++.h>
#define N 1005
using namespace std;
int n,m,ans,p[N];
char a[N],b[N];

void GetP() {
    p[1]=0; 
    int j=0;
    for(int i=2;i<=m;i++) {
        while(j&&b[i]!=b[j+1]) j=p[j];
        if(b[i]==b[j+1]) j++;
        p[i]=j;
    }
}
void KMP() {
    int j=0;
    for(int i=1;i<=n;i++) {
        while(j&&a[i]!=b[j+1]) j=p[j];
        if(a[i]==b[j+1]) j++;
        if(j==m) ans++,j=0; //从头开始重新匹配,保证不重叠
    }
}

int main() {
    while(scanf("%s%s",a+1,b+1)==2) {
        n=strlen(a+1),m=strlen(b+1);
        ans=0; GetP(),KMP();
        printf("%d\n",ans);
    }
}

 

Power Strings

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,p[N];
char s[N];

void GetP() {
    p[1]=0; 
    int j=0;
    for(int i=2;i<=n;i++) {
        while(j&&s[i]!=s[j+1]) j=p[j];
        if(s[i]==s[j+1]) j++;
        p[i]=j;
    }
}

int main() {
    while(scanf("%s",s+1)) {
        if(s[1]=='.') break;
        n=strlen(s+1);
        GetP(); 
        if(n%(n-p[n])==0) 
         printf("%d\n",n/(n-p[n]));
        else puts("1");
    }
}

 

似乎在梦中见过的样子

#include<bits/stdc++.h>
using namespace std;
const int N=1.5*1e4+5;
int n,k,ans,p[N];
char s[N];

int main() {
    scanf("%s%d",s+1,&k);
    n=strlen(s+1);
    for(int l=1;l<=n-2*k;l++) { //枚举子串左端点 
        p[l]=l-1;
        int j=l-1,x;
        for(int i=l+1;i<=n;i++) { //枚举子串右端点 
            while(j>l-1&&s[i]!=s[j+1]) j=p[j];
            if(s[i]==s[j+1]) j++;
            x=p[i]=j;
            while(2*(x-l+1)>=i-l+1) x=p[x];
            if(x-l+1>=k) ans++;
        }
    }
    printf("%d",ans);
}

 

posted @ 2019-02-14 15:59  YeLingqi  阅读(229)  评论(0编辑  收藏  举报