字符串哈希

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 字符串哈希,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

原题链接841. 字符串哈希 – AcWing题库 

 视频讲解AcWing 841. 字符串哈希 – AcWing

 字符串哈希

 全称字符串前缀哈希法,把字符串变成一个p进制数字(哈希值)实现不同的字符串映射不同的数字

对形如 X1X2X3⋯Xn−1Xn 的字符串,采用字符的ascii 码乘上 P 的次方来计算哈希值。

映射公式 

字符串哈希

比较不同区间的子串是否相同,就转化为对应的哈希值是否相同

求一个字符串哈希值就相当于求前缀和,

求一个字符串的子串哈希值就相当于求区间和 

字符串哈希 区间和公式的理解: ABCDE 与 ABC 的前三个字符值是一样,只差两位,
乘上P的二次方把 ABC 变为 ABC00,再用 ABCDE – ABC00 得到 DE 的哈希值

字符串哈希 

 

使用:typedef unsigned long long,得到的哈希值就不用取模了,因为unsigned long long会把溢出的部分自动取模 

字符串哈希

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e5+5,t = 131;//131 13331(经验值)
ULL h[N],p[N];

// h[i]前i个字符的hash值
// 字符串变成一个p进制数字,体现了字符+顺序,需要确保不同的字符串对应不同的数字
// t = 131 或  13331 在99%的情况下不会出现冲突
// 使用场景: 两个字符串的子串是否相同
ULL query(int l,int r){
    return h[r] - h[l-1]*p[r-l+1];
}
int main(){
    int n,m;
    cin>>n>>m;
    string x;
    cin>>x;

    //字符串从1开始编号,h[1]为前一个字符的哈希值
    p[0] = 1;
    h[0] = 0;
    for(int i=1;i<=n;i++){
        p[i] = p[i-1]*t;            
        h[i] = h[i-1]*t +x[i];      //前缀和求整个字符串的哈希值
    }

    while(m--){
        int l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;
        if(query(l1,r1) == query(l2,r2)) printf("Yes\n");
        else printf("No\n");

    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/131405.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!