您的位置:首页 > 其它

hdu 1686 kmp(求子串出现个数)

2016-07-21 10:44 253 查看
点击打开链接

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int M =1010000;
char a[M],b[10100];
int Next[M],n,m,lb,la;
void Get()
{
Next[0]=-1;
int i=0,k=-1;
while(i<lb)
{
if(k==-1||b[i]==b[k])
{
Next[i+1]=k+1;
i++;
k++;
}
//自己匹配自己
// next[i]=k "b1...bk-1" == " bi-(k-1) .. bi-1 "
// 当bk回溯到bk'时 -> : "b1..bk'-1" == "bk-(k'-1)...bk-1"
// next[i]=k "bk-(k'-1)...bk-1" == " bi-k'-1 .. bi-1"
//"b1..bk'-1" == " bi-k'-1 .. bi-1" 直到 bk'==bi 即next[i+1]=k'+1
else
{
k=Next[k];
}

}
}
void Kmp()
{
int ans=0;
int i=0,k=0;
while(i<la)
{
if(k==-1||a[i]==b[k])
{
i++;
k++;
if(k==lb)// 匹配成功
{
ans++;
// 本来匹配成功后 最朴素应该 k=0 i=i-lb+1 然后继续比较 -> TLE 太慢
// 如果不回溯主串 应该用模式串第几位于i比较? 因为k=lb b[k]!=a[i] 所以回溯到k=next[k]
k=Next[k];//
}
}
else
{
k=Next[k];
}
}
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%s%s",b,a);
la=strlen(a);
lb=strlen(b);
Get();
Kmp();

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: