hdu 2087 剪花布条 kmp模板题

时间:2023-03-09 18:29:15
hdu 2087	剪花布条 kmp模板题

也是kuangbin专题的 专题名字太长 不复制了……

刚好数据结构也学了kmp 找一道题敲敲模板……

暴力的字符串匹配是O(n*m)的时间复杂度

而kmp通过一个O(m)的预处理将字符串匹配的时间复杂度降到了O(n+m)

kmp的核心是next数组的处理和利用next数组进行字符串匹配

这两个理解了就会用kmp了

 /* ***********************************************
Author :Sun Yuefeng
Created Time :2016/10/31 19:02:08
File Name :kmp.cpp
************************************************ */ #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<bitset>
#include<map>
#include<set>
#include<stack>
#include<vector>
#include<queue>
#include<list>
#define M(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=;
const int mod=1e7+;
int dx[]= {,,,-,,-,,-};
int dy[]= {,-,,,-,,,-}; char str[maxn];
char f[maxn];
int _next[maxn]; /************************************
next数组的含义就是:
第0位的默认为0
以当前字符为结尾的字符串的最长公共前后缀长度
例如:
loc 0 1 2 3 4 5 6
str A B C A B C D
next 0 0 0 1 2 3 0
*************************************/ void kmp(char str[],int len) //预处理next数组
{
int i=,j=-;
_next[]=-;
while(i<len)
{
while(-!=j&&str[i]!=str[j]) j=_next[j];
i++,j++;
_next[i]=j;
}
} int cnt(char x[],int lenx,char y[],int leny) //查找
{//x是模式串 y是主串
int i=,j=,ans=;
M(_next,);
kmp(f,strlen(f));
while(i<leny)
{
while(-!=j&&y[i]!=x[j]) j=_next[j];
i++,j++;
if(j>=lenx)
{
ans++;
j=;
//j=next[j];
//如果换成上面这句的话 模式串是可以重复的
}
}
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>str)
{
if(str[]=='#') break;
cin>>f;
cout<<cnt(f,strlen(f),str,strlen(str))<<endl;
}
return ;
}