当前位置: 首页 > article >正文

AcWing 841. 字符串哈希

字符串哈希

一种将任意长度的字符串转换为固定长度数值(通常是整数)的过程。全称字符串前缀哈希法,把字符串变成一个p进制数字(哈希值),实现不同的字符串映射到不同的数字。
对形如 X1X2X3⋯Xn−1Xn
 的字符串,采用字符的ascii 码乘上 P 的次方来计算哈希值。

映射公式

(X1×Pn−1+X2×Pn−2+⋯+Xn−1×P1+Xn×P0)modQ

把一个字符串哈希成一个数字:

①定义某个字符串前缀的哈希值:把字符串看成一个P进制的数,每一位上的字母表示P进制上的每一位数字

②把P进制数转换十进制数,最后对整个数模上一个Q,这样可以把任何一个字符串映射到从0~Q-1之间的数了。

注意

①不能把任意字符映射成0,否则会出现不同的字符串都映射成0的情况,比如A,AA,AAA皆为0

②Rp足够好,不存在冲突

解决冲突问题:(经验)p=131或13331时,Q=2的64次方,一般可以理解为不产生冲突。

82e22c8a3a274a2d9f1615b76e456cca.png

这种哈希方式搭配前缀哈希的好处:

可以利用我们求得的所有前缀哈希,用一个公式求出所有字符串的哈希值

转化

比较不同区间的子串是否相同,就转化为对应的哈希值是否相同。
求一个字符串的哈希值就相当于求前缀和,求一个字符串的子串哈希值就相当于求部分和。

前缀和公式

h[i+1]=h[i]×P+s[i]

h为前缀和数组,s为字符串数组

区间和公式

h[l,r]=h[r]−h[l−1]×Pr−l+1

e302ea16b440498b8d44ccfa5e519607.png

AC代码

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

// h[i]前i个字符的hash值
// 字符串变成一个p进制数字,体现了字符+顺序,需要确保不同的字符串对应不同的数字
// P = 131 或  13331 Q=2^64,在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=0;i<n;i++){
        p[i+1] = p[i]*P;            
        h[i+1] = h[i]*P +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;
}


http://www.kler.cn/a/421121.html

相关文章:

  • 在 MacOS 上为 LM Studio 更换镜像源
  • 等差数列末项计算
  • vue2+cesium初始化地图
  • 什么是 Kubernetes(K8s)?
  • Git Rebase vs Merge:操作实例详解
  • 新手学习:网页前端、后端、服务器Tomcat和数据库的基本介绍
  • 深入探索进程间通信:System V IPC的机制与应用
  • PLC协议
  • eBPF:现代Linux的强大内核扩展技术
  • docker搭建umami
  • PHM技术:一维信号时序全特征分析(统计域/频域/时域)| 信号处理
  • 【机器人】01 强化学习、模仿学习和运动规划 仿真平台ISAAC Lab安装与使用
  • 代码随想录-算法训练营day31(贪心算法01:分发饼干,摆动序列,最大子数组和)
  • 【CUDA】Kernel Atomic Stream
  • python学opencv|读取视频(一)灰度视频制作和保存
  • Nginx 转发代理天地图服务
  • adb导出系统apk
  • vulnhub靶场【哈利波特】三部曲之Aragog
  • std::thread()函数的第一个参数的使用细节
  • FreeSWITCH mod_conference 的按键会控
  • 【C++】智能指针的使用和原理
  • 总结拓展十七:特殊采购业务——委外业务
  • 数据结构——有序二叉树的删除
  • 【Tr0ll2靶场渗透】
  • 帮我写一篇关于AI搜索网页上编写的文章是否存在版权问题的文章, 字数在 3000 字左右。文心一言提问, 记录后用.
  • Erlang数据库:Mnesia(一) —— 数据库查询