字符串Hash(可处理一些字符串问题)

字符串Hash模板:

//使用 hash[i]=(hash[i-1]*p+idx(s[i]))%mod 求得前缀为i的hash值,
//利用 hash[l..r]=(hash[r]-hash[l-1]*(p^(r-1+1)))%mod 求得s[l,r]的hash值.
//(注意l=0的问题,以及hash[l..r] < 0时要 +mod)
const ll p = 1e7+9;
const ll mod = 1e9+7;

ll Pow[N];
ll Hash[N];
char s1[1005];
char s2[1005];
int len1,len2;

void init()  //预处理字符串1的hash值
{
    Pow[0]=1;
    Hash[0]=s1[0]%mod;
    for(int i=1;i<=len1;i++)      //注意这里要处理到等于len1,因为算次幂有可能有这个值
        Pow[i] = Pow[i-1]*p%mod;  //预处理p的幂值
    for(int i=1;i<len1;i++)
        Hash[i]=(Hash[i-1]*p%mod)+s1[i]%mod;
}

ll get(int l,int r)
{
    if(l==0)
        return ((Hash[r]-0*Pow[r-l+1])%mod+mod)%mod;
    else
        return ((Hash[r]-Hash[l-1]*Pow[r-l+1])%mod+mod)%mod;
}

int Get_count()   //求出s2在s1中出现次数,不可重叠
{
    init();
    ll haha = 0;
    for(int i=0;i<len2;i++)
        haha = (haha*p%mod+s2[i]%mod)%mod;  //求出匹配串s2的hash值
    ll res=0;
    for(int i=0;i+len2-1<len1;)
    {
        ll hs = get(i,i+len2-1)%mod;
        if(hs==haha)
        {
            i+=len2;
            res++;
        }
        else
            i++;
    }
    return res;
}

猜你喜欢

转载自blog.csdn.net/baodream/article/details/80367441