A string is a finite sequence of symbols that are chosen from an alphabet. In this problem you are given two non-empty strings A and B, both contain lower case English alphabets. You have to find the number of times B occurs as a substring of A.
Input
Input starts with an integer T (≤ 5), denoting the number of test cases.
Each case starts with two lines. First line contains A and second line contains B. You can assume than 1 ≤ length(A), length(B) ≤ 106.
Output
For each case, print the case number and the number of times B occurs as a substring of A.
Sample Input
4
axbyczd
abc
abcabcabcabc
abc
aabacbaabbaaz
aab
aaaaaa
aa
Sample Output
Case 1: 0
Case 2: 4
Case 3: 2
Case 4: 5
Note
Dataset is huge, use faster I/O methods.
题目大意:求字符串b在字符串a中的出现次数。
解题思路:套用KMP板子,然后在找到了一个字符串之后,将j跳到满足条件的后一个位置。
代码:
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <bitset>
#include <queue>
//#include <random>
#include <time.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define ls root<<1
#define rs root<<1|1
const int maxn=1e6+10;
const int maxm=3e6+10;
//std::mt19937 rnd(time(NULL));
int to[maxn],len1,len2;
char a[maxn],b[maxn];
void init()
{
to[0]=-1;
for(int i=1;b[i]!='\0';i++){
int t=to[i-1];
while(t>=0 && b[t+1]!=b[i])t=to[t];
if(b[t+1]==b[i])to[i]=t+1;
else to[i]=-1;
}
}
int kmp()
{
init();
int ans=0,i=0,j=0;
while(a[i]!='\0'){
if(a[i]==b[j]){
i++,j++;
if(b[j]=='\0'){
ans++;
j=to[j-1]+1;
}
}
else{
if(j==0) i++;
else j=to[j-1]+1;
}
}
return ans;
}
signed main()
{
int t,test=1;
scanf("%lld",&t);
while(t--){
memset(a,0,sizeof a);
memset(b,0,sizeof b);
scanf("%s%s",a,b);
printf("Case %lld: %lld\n",test++,kmp());
}
}