HUD1686-Oulipo-kmp模板题/哈希模板题
测试数据
Sample Input
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
Sample Output
1
3
0
题意
计算模式串在原串中出现的次数
KMP
-
对于next数组的理解是理解kmp的关键。
-
next[i]:记录的是前后缀最长公共长度。
AC代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int N=1000020;
const int M=10020;
char s[N];//原串
char t[M];//模式串
int nextt[M];
void getnext(int len)//求的是模式串的next数组
{
int i=0,j=-1;
nextt[0]=-1;
while(i<len)
{
if(j<0||t[i]==t[j])
nextt[++i]=++j;
else
j=nextt[j];
}
}
int kmp(int m,int n)//m模式串长度、n原串长度
{
int i=0,j=0,ans=0;
while(i<n)
{
if(j==-1||t[j]==s[i])
{
i++;
j++;
}
else
j=nextt[j];
if(j==m)
{
ans++;
j=nextt[j];
}
}
return ans;
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
memset(s,'\0',sizeof(s));
memset(t,'\0',sizeof(t));
memset(nextt,0,sizeof(nextt));
scanf("%s%s",t,s);//模式串、原串
int len1=strlen(t);//模式串
int len2=strlen(s);//原串
getnext(len1);
printf("%d\n",kmp(len1,len2));
}
return 0;
}
哈希
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string.h>
#include<queue>
#include<map>
using namespace std;
typedef unsigned long long ull;
const int N=1e6+20;
char a[N],b[N];
ull p[N],sum[N],x=131;
//求a(子串)在b(母串)中出现多少次
void w()
{
p[0]=1;
for(int i=1; i<1000000; i++)
p[i]=p[i-1]*x;//预处理出x^n
}
int main()
{
w();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s %s",a+1,b+1);//使得下标从1开始
int la=strlen(a+1);//短
int lb=strlen(b+1);//长
sum[0]=0;
for(int i=1; i<=lb; i++)
sum[i]=sum[i-1]*x+(ull)(b[i]-'A'+1);
ull s=0;
for(int i=1; i<=la; i++)
s=s*x+(ull)(a[i]-'A'+1);//*x是为了化成x进制数
int ans=0;
for(int i=0; i<=lb-la; i++)
{
if(s==sum[i+la]-sum[i]*p[la])
ans++;
}
printf("%d\n",ans);
}
return 0;
}
问题
不明白为什么哈希的时间比kmp慢而且占用的内存都快是kmp的10倍了???