hdu 1711 Number Sequence(kmp找子串第一次出现的位置)
题意:裸kmp
思路:kmp模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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("\t位置:%d 个数:%d\n",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\n",KMPIndex(s,t,n,m)); } return 0; }