hdu 1711 Number Sequence(kmp找子串第一次出现的位置)

题意:裸kmp

思路:kmp模板

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

#define MaxSize 10005

int s[1000005],t[10005];
int next2[MaxSize];

void GetNext(int t[],int len){//求next数组
    int j,k;//,len;
    j=0;
    k=-1;
    next2[0]=-1;
    //len=strlen(t);
    while(j<len){
        if(k==-1||t[j]==t[k]){
            ++j;
            ++k;
            next2[j]=k;//此句可由优化替代
            /*优化(仅保证求KMPIndex时可用。谨慎使用。)
            if(t[j]!=t[k])next[j]=k;
            else next[j]=next[k];
            */
        }
        else k=next2[k];
    }
}

int KMPIndex(int s[],int t[],int lens,int lent){//求子串首次出现在主串中的位置
    int i,j;//,lens,lent;
    i=j=0;
    //lens=strlen(s);
    //lent=strlen(t);

    while(i<lens&&j<lent){
        if(j==-1||s[i]==t[j]){
            ++i;
            ++j;
        }
        else j=next2[j];
    }
    if(j>=lent)return i-lent+1;
    else return -1;
}

int KMPCount(char s[],char t[]){//统计子串在主串中的出现次数,可重叠
    int i,j,lens,lent,cnt;
    i=j=0;
    lens=strlen(s);
    lent=strlen(t);
    cnt=0;

    while(i<lens){
        if(j==-1||s[i]==t[j]){
            ++i;
            ++j;
        }
        else j=next2[j];
        if(j==lent)++cnt;
    }
    return cnt;
}

void KMPCount2(char t[]){//统计单串中从某个位置以前有多少重复的串
    int i,lent,tmp;
    lent=strlen(t);

    for(i=2;i<=lent;++i){
        tmp=i-next2[i];
        if(i%tmp==0&&i/tmp>1)
            printf("	位置:%d 个数:%d
",i,i/tmp);
    }
}

int main(){
    int tt,n,m,i;
    scanf("%d",&tt);
    while(tt--){
        scanf("%d%d",&n,&m);
        for(i=0;i<n;++i)
            scanf("%d",&s[i]);
        for(i=0;i<m;++i)
            scanf("%d",&t[i]);
        GetNext(t,m);
        printf("%d
",KMPIndex(s,t,n,m));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/gongpixin/p/4729491.html