剪花布条
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14793 Accepted Submission(s): 9376
Problem Description
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
Sample Input
abcde a3 aaaaaa aa #
Sample Output
0 3
题目大意:给定字符串a和b,求b在a中出现的次数
思路:KMP算法模板题,只不过在kmp时,返回的不是b在a中出现的起始位置,应该改成答案(ans)加一,然后把j置为0,继续比对
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
const int maxn = 1000+5;
int ans,Next[maxn];
void getNext(string s)
{
int ls=s.size();
Next[0]=-1;
Next[1]=0;
for(int i=2;i<=ls;i++){
if(s[i-1]==s[Next[i-1]]) Next[i]=Next[i-1]+1;
else{
int t=Next[i-1];
while(s[i-1]!=s[t]){
t=Next[t];
if(t==-1) break;
}
Next[i]=t+1;
}
}
}
void kmp(string a,string b)
{
getNext(b);
int la=a.size(),i=0;
int lb=b.size(),j=0;
while(i<la && j<lb){
if(j==-1 || a[i]==b[j]) i++,j++;
else j=Next[j];
if(j==lb) ans++,j=0;
}
}
int main()
{
cin.sync_with_stdio(false);
string a,b;
while(cin>>a){
if(a[0]=='#') break;
cin>>b;
ans=0;
kmp(a,b);
cout<<ans<<endl;
}
return 0;
}