字符串哈希模板+子串判重---字符串哈希

文章介绍了字符串哈希的计算方法,通过将字符串视为特定进制的整数并结合模运算避免溢出,以及如何利用前缀和思想计算区间哈希。在给定的C++代码示例中,展示了如何快速判断两个子串是否重复,这种方法常用于字符串处理问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//  字符串哈希原理

// 举例:
将字符串 s="abcd"视为26进制整数,
hash(s)=1*26^3+2*26^2+3*26^1+4*26^0;
如果字符串很长,h(s)很容易超出 long long 值;
所以:  hash(s)%h;(h和26互质&&h尽可能大)
/*-----------------------------------------------------*/
// 注:
一般来说:进制取 131,13331,模取 2^64
(long long 范围:2^63-1,所以应该用unsigned long long )
/*------------------------------------------------------*/

//模板:
1,前缀和思想计算哈希
h[i-1] -> 1~i-1的哈希值
h[i]=h[i-1]*b+(s[i]-'a'+1);
2,计算区间哈希
s=123456789
h[6]=123456              h[r]
h[4]=1234                h[l-1]
h[5,6]=h[6]-h[4]*10^2;   h[l,r]=h[r]-h[l-1]*b^(r-(l-1));
/*-------------------------------------------------------*/

1915-【基础】子串判重
来源: 东方博宜oj     oj.czos.cn
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N=1e6+10,P=131;
//h[i]:1~i区间中子串的哈希值
// p[i]:P的i次方
ULL h[N],p[N];
char s[N];
int m;

// 返回字符串子区间的哈希值(计算区间哈希)
ULL get(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];
}
int main()
{
    scanf("%s",s+1);
    //计算h[]和p[]的值
    p[0]=1;
    int len=strlen(s+1);
    // 计算哈希
    for(int i=1;i<=len;i++)
    {
        p[i]=p[i-1]*P;
        h[i]=h[i-1]*P+(s[i]-'a'+1);
    }
    scanf("%d",&m);
    int l1,r1,l2,r2;
    while(m--)
    {
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        //如果两个子区间的哈希值相同
        if(get(l1,r1)==get(l2,r2))  printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值