#include<stdio.h>
#include<string.h>
int a[1111111],b[1000000];
int next[11111];
void getNext(int *bb,int b){
next [0] = next[1] = 0;
for(int i=1;i<b;i++){
int j = next[i];
while(j&&bb[i]!=bb[j])j = next[j];
next[i+1] = bb[i] == bb[j]?j+1:0;
}
}
int main()
{ int i,j,temp,n,m,flag;
int q;scanf("%d",&q);
while(q--)
{scanf("%d%d",&n,&m);
flag=0;
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<m;i++) scanf("%d",&b[i]);
getNext(b,m);
j=0;
for(i=0;i<n;i++){
while(j&&a[i] != b[j])j = next[j];
if(a[i] == b[j])j++;
if(j == m){flag = 1;break;}
}
if(flag)
printf("%d\n",i-m+2);
else printf("-1\n");
}
}
就是套模版,next,然后匹配。
#include<stdio.h>
#include<string.h>
int next[10010],len1,len2;
void getnext(char *s)
{
int i=0,j=-1;
next[0]=-1;
while(i<len1)
{
if(j==-1||s[i]==s[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
int main()
{ int i,j,temp,n,m,flag;
char a[1111],b[1111],d[5]="#";
while(scanf("%s",&a)!=EOF){flag=0;
if(strcmp(a,d)==0) break;
scanf("%s",&b);
n=strlen(a);m=strlen(b);
getnext(b);
j=0;
for(i=0;i<n;i++){
while(j&&a[i] != b[j])j = next[j];
if(a[i] == b[j])j++;
if(j == m){flag++;j=0;}
}
printf("%d\n",flag);
}
}
两道题做法一样,NEXT函数不太一样,因为找NEXT函数方法太多了,我就多试试看,这两个也可以换换next。
做了几个题,一般处理位置
if(j == m){flag++;j=0;}
这个是花布条的,因为要找多次,NS那道题只找第一个,然后break。别的题(简单的纯kmp题)大多也是这里不同。