POJ - 3461 Oulipo (kmp或hash)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a54665sdgf/article/details/81429914

题目大意:给你两个字符串s1和s2,让你求s2在s1中出现的次数。

kmp:(标准解法)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#define FRER() freopen("i.txt","r",stdin)
#define FREW() freopen("o.txt","w",stdout)

using namespace std;
typedef long long LL;
const int N=10000+10;
const int M=1000000+100;
char s1[M],s2[N];
int nxt[N];

void GetNext(const char* s)
{
    int len=strlen(s);
    nxt[0]=nxt[1]=0;
    for(int i=1,j; i<len; ++i)
    {
        j=nxt[i];
        while(j&&s[i]!=s[j])
            j=nxt[j];
        nxt[i+1]=s[i]==s[j]?j+1:0;
    }
}

int Match(const char* s1,const char* s2)
{
    GetNext(s2);
    int len1=strlen(s1),len2=strlen(s2);
    int cnt=0;
    for(int i=0,j=0; i<len1; ++i)
    {
        while(j&&s1[i]!=s2[j])
            j=nxt[j];
        if(s1[i]==s2[j])
            ++j;
        if(j==len2)
            ++cnt;
    }
    return cnt;
}

int main()
{
    //FRER();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s2,s1);
        printf("%d\n",Match(s1,s2));
    }
    return 0;
}

hash:(能不能AC看脸,只要不是极品非酋就能过)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#define FRER() freopen("i.txt","r",stdin)
#define FREW() freopen("o.txt","w",stdout)

using namespace std;
typedef unsigned long long ll;
const int N=10000+10;
const int M=1000000+100;
const ll p=1e9+7;
char s1[M],s2[N];
int l1,l2;
ll H1[M],H2[N],P[N];

ll Hash(int l,int r)
{
    return H1[r]-H1[l-1]*P[r-l+1];
}

int main()
{
    //FRER();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s2,s1);
        l1=strlen(s1);
        l2=strlen(s2);
        H1[0]=H2[0]=0;
        for(int i=1;i<=l1;++i)
            H1[i]=H1[i-1]*p+s1[i-1];
        for(int i=1;i<=l2;++i)
            H2[i]=H2[i-1]*p+s2[i-1];
        P[0]=1;
        for(int i=1;i<=l2;++i)
            P[i]=P[i-1]*p;
        int cnt=0;
        for(int i=1;i<=l1-l2+1;++i)
        if(Hash(i,i+l2-1)==H2[l2])++cnt;
        printf("%d\n",cnt);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a54665sdgf/article/details/81429914