CSU 1598: 最长公共前缀 KMP
Description
给定两个字符串s和t,现有一个扫描器,从s的最左边开始向右扫描,每次扫描到一个t就把这一段删除,输出能发现t的个数。
Input
第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个字符串s,第二行一个字符串t,字符串长度不超过1000000。
Output
对于每组数据,输出答案。
Sample Input
2 ababab ab ababab ba
Sample Output
3 2
Hint
Source
国防科学技术大学第十八届银河之光文化节ACM程序设计竞赛初赛思路: KMP模板题
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
//include <map>
using namespace std;
char s1[1000005];
char s2[1000005];
int Next[1000005];
int n,m;
int ans;
int match()
{
for(int i = 0 , j = 0 ; i < n ;)
{
if(s1[i] == s2[j]){
i++,j++;
if(j == m){
ans++;
j = 0;
}
}else if(j == 0) i++;
else j = Next[j];
}
return -1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%s%s",s1,s2);
n = strlen(s1);
m = strlen(s2);
ans = 0;
Next[0] = Next[1] = 0;
for(int i = 1 ; i < m ; i++){
int k = Next[i];
while(s2[i] != s2[k] && k != 0)
k = Next[k];
if(s2[i] == s2[k])
Next[i+1] = k + 1;
else Next[i+1] = 0;
}
match();
cout<<ans<<endl;
}
return 0;
}