几道简单的可以用KMP解答的题目,也是刚学KMP时做的。
学习KMP给我最大帮助的是此博文:http://www.matrix67.com/blog/archives/115/
(要是对KMP还不是太懂的,建议去看看此博文)
题意就是给两个字符串W和T,问W在T中出现的次数。
代码:
#include<stdio.h>
#include <string.h>
char a[1000002],b[10002];
int p[10002];
int n,m,num;
int kmp()
{
num=0;
p[0]=-1;
int i,j=-1;
for(i=1;i<m;i++){
while(j>-1&&b[j+1]!=b[i]) j=p[j];
if(b[j+1]==b[i]) j+=1;
p[i]=j;
}
j=-1;
for(i=0;i<n;i++){
while(j>-1&&b[j+1]!=a[i]) j=p[j];
if(b[j+1]==a[i]) j+=1;
if(j==m-1){
num++;
j=p[j];
}
}
return num;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",b);
scanf("%s",a);
m=strlen(b);
n=strlen(a);
printf("%d\n",kmp());
}
return 0;
}
HDU 1711 Number Sequence
题意很简单,就不解释了~~
代码:
#include<stdio.h>
#include <string.h>
int a[1000001],b[10001],p[10001];
int n,m;
int kmp()
{
p[1]=0;
int i,j=0;
for(i=2;i<=m;i++){
while(j>0&&b[j+1]!=b[i]) j=p[j];
if(b[j+1]==b[i]) j+=1;
p[i]=j;
}
j=0;
for(i=1;i<=n;i++){
while(j>0&&b[j+1]!=a[i]) j=p[j];
if(b[j+1]==a[i]) j+=1;
if(j==m){
return i-j+1;
j=p[j];
}
}
return -1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
printf("%d\n",kmp());
}
return 0;
}
HDU 2203 亲和串
这题就循环移位稍思考一下,只需将与串s1对应的变量i扩大(m/n+2)倍再用%就可解决,这题扩大两倍也能AC,不知是测试数据弱还是我理解错了~~
代码:
#include <stdio.h>
#include <string.h>
#define MAX 100002
char a[MAX*2],b[MAX],p[MAX];
int n,m;
int kmp()
{
p[1]=0;
int i,j=0;
for(i=2;i<=m;i++)
{
while(j>0&&b[j+1]!=b[i]) j=p[j];
if(b[j+1]==b[i]) j+=1;
p[i]=j;
}
j=0;
for(i=0;i<(m/n+2)*n;i++)
{
while(j>0&&b[j+1]!=a[i%n]) j=p[j];
if(b[j+1]==a[i%n]) j+=1;
if(j==m){
return 1;
j=p[j];
}
}
return 0;
}
int main()
{
while(~scanf("%s",a))
{
scanf("%s",b+1);
n=strlen(a);
m=strlen(b+1);
if(kmp())puts("yes");
else puts("no");
}
return 0;
}