Problem Description
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
Sample Input
abcde a3
aaaaaa aa
#
Sample Output
0
3
题解:
kmp算法。
或者STL暴力求。
注意模式串不能重叠。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1000+10;
int nt[maxn];
char s[maxn],t[maxn];
int slen,tlen;
void getNext()
{
int j,k;
j=0;k=-1;nt[0]=-1;
while(j<tlen)
{
if(k==-1||t[j]==t[k])
{
nt[++j]=++k;
}
else
{
k=nt[k];
}
}
}
int KMP_count()
{
int ans=0;
int i,j=0;
if(slen==1&&tlen==1)
{
if(s[0]==t[0])
{
return 1;
}
else
return 0;
}
getNext();
for(i=0;i<slen;i++)
{
while(j>0&&s[i]!=t[j])
j=nt[j];
if(s[i]==t[j])
j++;
if(j==tlen)
{
ans++;
j=0;//相当于重新看待主串和模板串的关系,去掉前面已匹配的主串成为新串,故清零j
}
}
return ans;
}
int main()
{
while(scanf("%s",s))
{
if(s[0]=='#') break;
scanf("%s",t);
slen = strlen(s);
tlen = strlen(t);
cout<<KMP_count()<<endl;
}
return 0;
}
代码:STL
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
string a,b,demo;
while(cin>>a&&a[0]!='#'){
cin>>b;
int siza=a.size();
int sizb=b.size();
int count=0;
for(int i=0;i<=siza-sizb;i++)
{
demo = a.substr(i,sizb);
if(demo.compare(b)==0){
count++;
i+=sizb-1;
}
}
cout<<count<<endl;
}
return 0;
}