1. 程式人生 > >LOJ103 子串查找

LOJ103 子串查找

大寫 gist 模板題 大寫字母 字符串 getc 復雜度 bits base

題意

這是一道模板題。

給定一個字符串 A 和一個字符串 B ,求 B 在 A 中的出現次數。A 和 B 中的字符均為英語大寫字母或小寫字母。

A 中不同位置出現的 B 可重疊。

分析

參照jklover的題解。

此題用hash做的話,只需求出字符串b的hash值,在字符串a中O(n)枚舉每個長度等於|b|的子串,判斷hash值是否相等即可.

時間復雜度:線性。

代碼

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
    rg T data=0;
    rg int w=1;
    rg char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return data*w;
}
template<class T>il T read(rg T&x)
{
    return x=read<T>();
}
typedef unsigned long long ull;
co int N=1e6+1;
co ull Base=233;
ull Hash[N],Pow[N];
char a[N],b[N];
int n,m;

ull calchash(int l,int len)
{
    return Hash[l+len-1]-Hash[l-1]*Pow[len];
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    scanf("%s%s",a+1,b+1);
    n=strlen(a+1),m=strlen(b+1);
    ull hashb=0;
    for(int i=1;i<=m;++i)
        hashb=hashb*Base+b[i];
    Pow[0]=1;
    for(int i=1;i<=n;++i)
    {
        Hash[i]=Hash[i-1]*Base+a[i];
        Pow[i]=Pow[i-1]*Base;
    }
    int ans=0;
    for(int i=1;i+m-1<=n;++i)
        if(calchash(i,m)==hashb)
            ++ans;
    printf("%d\n",ans);
    return 0;
}

LOJ103 子串查找