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

数据结构 哈希表 字符串哈希

字符串哈希表

将字符串转换为一个P进制的纯数字

每个字符,代表P进制上的一位。

abc和ab中的a,代表的值就不一样了

一个a是a的asc码*p的一次方,一个是a是a的asc码的*p的二次方

如图,abcde字符串对应的其哈希值

如上图所示

五个数的和,就是字符串的哈希值,这哈希值是唯一的

只有字符相同,长度相同,字符所在位置完全相同,字符串的哈希值才完全相同

为了避免哈希值重复,我们一般选择p=131或者p=13331

p的值

一般选择p=131 或 p=13331

  • 质数的特性:131131 和 1333113331 是质数。质数作为基数能更均匀地分散字符串的哈希值,避免因字符分布规律导致的碰撞。
  • 经验验证:这两个值在实践中被广泛测试,证明它们在绝大多数场景下能有效降低冲突概率。
  • 自然溢出优化:当使用 unsigned long long 存储哈希值时,P×字符asc码 的乘法会自然溢出(等价于模 2的六十四次方),无需显式取模。

哈希值前缀和数组推导公式

h[N]设置为存储哈希值的数组,例如h[i],就是字符串第1个到第i个的哈希值

str[i]代表字符串中第i个字符的asc码

则h[i]=

h[i] = h[i-1]*P+str[i];

i-1是字符串的前一位

例如ab字符串添加c

ab*p,p进制哈希值,代表ab都进一位,得结果为ab0,添加c,得abc字符串哈希值

利用字符串哈希表查询

字符串哈希的题,往往会让我们查找L1-R1和L2-R2是否为相同字符串

拆开来看,就是查找字符串,指定区间内的哈希值

其实我们直接用前缀和的思想思考即可

例如查找l-r区间内字符串的哈希值

h[r]是前r个字符串的哈希值

h[l-1]是L前的字符串的哈希值

举例

字符串abcde,求3-5区间的哈希值,r为5,l为3

h[5]为h[r],也就是h[r]的哈希值是abcde

然后h[l-1],也就是h[2]的哈希值是ab

我们想求的l-r区间,实际上就是想求cde的哈希值

如果得到cde的哈希值,需要减去ab

但是h[2]的哈希值的ab,是两位数ab

abcde里的ab,实际上是ab000,所以想要得到cde的哈希值,需要ab000-abcde

我们知道,字符串的哈希值是p进制,那让ab变成ab000,只需要ab*p*p*p

也就是ab*p的(r-l+1)次方

设X为L-R字符串区间哈希值,得公式

ULL  x=h[r]-h[l-1]*p[r-l+1];

经典例题和完整代码

AcWing - 算法基础课

#include<iostream>
using namespace std;
#define ULL unsigned long long
// typedef unsigned long long ULL;
const int N = 100003;
const int P = 131;
int p[N],h[N];//p[i]存储的是p的i次方,例如p[2]存储p的2次方
//返回区间字符串的哈希值
ULL que(int l,int r){
    return h[r]-h[l-1]*p[r-l+1];
}
int main(){
    int n,m;
    cin>>n>>m;
    char str[N];
    cin>>str+1;
    p[0]=1;
    h[0]=0;
    for(int i=1;i<=n;i++){
    //同时初始化p[N],存储p的次方
    p[i] = p[i-1]*P;
    //前缀和求整个字符串哈希值   
    h[i] = h[i-1]*P+str[i];
    }
    while(m--){
        int l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;
        cout<<(que(l1,r1)==que(l2,r2)?"Yes":"No")<<endl;
    }
    return 0;
}

http://www.dtcms.com/a/105113.html

相关文章:

  • VMware安装Ubuntu实战分享
  • 【算法学习计划】贪心算法(下)
  • 在ensp进行OSPF+RIP+静态网络架构配置
  • [GESP202503 C++六级题解]:P11963:环线
  • 关于VMware Tools 不再随旧版客户机操作系统的 VMware Workstation 一起提供。
  • 高级java每日一道面试题-2025年3月22日-微服务篇[Nacos篇]-Nacos的主要功能有哪些?
  • TBKDVR硬盘录像机device.rsp命令执行漏洞
  • CISCO路由器配置DHCP中继
  • YOLOv12即插即用-Pconv(风车卷积)
  • QT自定义信号与槽
  • NHANES指标推荐:TyG-BMI
  • 自然语言处理|如何用少样本技术提升低资源语言处理?
  • acwing 5438. 密接牛追踪2
  • MaxEnt物种分布建模全流程;R+ArcGIS+MaxEnt模型物种分布模拟、参数优化方法、结果分析制图与论文写作
  • Minimind 训练一个自己专属语言模型
  • 什么是BSCI验厂?BSCI验厂的好处?BSCI验厂的意义
  • 小程序29-事件穿参-mark 自定义数据
  • 基于SpringBoot的“考研学习分享平台”的设计与实现(源码+数据库+文档+PPT)
  • 【更新至2023年】1987-2023年各省专利申请授权数据(8个指标)
  • 自然语言处理(28:(终章Attention 4.)关于Attention的其他话题)
  • 1KHZ的带通滤波器设计与仿真
  • 动态规划入门:从记忆化搜索到递推
  • 华为IP(3)
  • 去中心化借贷机制解析
  • MySQL 进阶 面经级
  • Oracle 数据库中优化 INSERT INTO 操作的性能
  • 量子计算与人工智能融合的未来趋势
  • 预训练(Pre-training) 和 微调(Fine-tuning)
  • 机器学习(总节环节)
  • 迈向云原生:理想汽车 OLAP 引擎变革之路