这是一道KMP模板题,但又有所不同,匹配的是差值相同的连续串。设原串a,b,c,d模式串是 e,f,g,h.
匹配的条件是a-e=b-f=c-g=d-h,即a-b=e-f, b-c=f-g, c-d=g-h.所以完全匹配的是两个串相邻数的差值即可,我把差值分别存起来,作为原串和模式串,其余的就是kmp模板了。*******就是当匹配类型是int 型而不是一般的char时,当str[]={0,0,0,0,0},mo[]={0, 0}答案是4但程序output为1,所以,我把里面的0全换为-1了。
#include<bits/stdc++.h>
const int maxn=200005;
using namespace std;
int str[maxn];
int mo[maxn];
int a[maxn];
int b[maxn];
int Next[maxn];
int n,m;
void getNext()
{
int i=0;
int j=-1;
int len=m-1;
while(i<len)
{
if(j==-1||mo[i]==mo[j])
{
i++;
j++;
Next[i]=j;
}
else j=Next[j];
}
}
int kmp()
{
int i=0;
int j=0;
int ans=0;
int l1=n-1;
int l2=m-1;
while(i<l1)
{
if(j==-1||(mo[j]==str[i]))
{
i++;
j++;
}
else j=Next[j];
if(j==l2) ans++;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(str,0,sizeof(str));
memset(mo,0,sizeof(mo));
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
str[i-1]=a[i]-a[i-1];
if(str[i-1]==0) str[i-1]=-1;
}
for(int i=0;i<m;i++)
scanf("%d",&b[i]);
for(int i=0;i<m;i++)
{
mo[i-1]=b[i]-b[i-1];
if(mo[i-1]==0) mo[i-1]=-1;
}
if(m==1)
{
printf("%d\n",n);
continue;
}
Next[0]=-1;
getNext();
printf("%d\n",kmp());
}
}