浏览器标题切换
浏览器标题切换end

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倍了???

posted @ 2019-08-21 20:14  抓水母的派大星  阅读(162)  评论(0编辑  收藏  举报