kuangbin专题十六 KMP&&扩展KMP HDU2087 剪花布条
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
Input输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
Output输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
Sample Input
abcde a3 aaaaaa aa #Sample Output
0 3
kmp裸题,不同的是不能重叠。
不能重叠 j=0 重叠的话是 j=Next[j]
比较好理解。因为不重叠就当前i和j=0 重叠就是当前i和Next[j],前面部分重叠(i之前的k个)
1 #include<stdio.h> 2 #include<string.h> 3 int Next[1010],n,m,tlen,plen; 4 char t[1010],p[1010]; 5 6 void prekmp() { 7 int i,j; 8 tlen=strlen(t); 9 plen=strlen(p); 10 j=Next[0]=-1; 11 i=0; 12 while(i<plen) { 13 while(j!=-1&&p[i]!=p[j]) j=Next[j]; 14 if(p[++i]==p[++j]) Next[i]=Next[j]; 15 else Next[i]=j; 16 } 17 } 18 19 int kmp() { 20 prekmp(); 21 int i,j,ans=0; 22 i=j=0; 23 while(i<tlen) { 24 while(j!=-1&&t[i]!=p[j]) j=Next[j]; 25 i++;j++; 26 if(j>=plen) { 27 ans++; 28 j=0;//不重叠 29 } 30 } 31 return ans; 32 } 33 34 int main() { 35 while(~scanf("%s",t)) { 36 if(t[0]=='#') break; 37 scanf("%s",p); 38 printf("%d\n",kmp()); 39 } 40 }
埋骨何须桑梓地,人生无处不青山