初识字符串哈希(Hash)

news2025/5/19 5:46:05

目录

1.字符串哈希的介绍

2.自然溢出哈希

3.单哈希

4.双哈希

5.例题分析

1.自然溢出哈希AC代码

2.单哈希AC代码

3.双哈希AC代码

6.总结


1.字符串哈希的介绍

字符串哈希是一种将字符串映射为一个固定长度的整数或哈希值的技术。它的主要目的是加速字符串比较和搜索操作,通常用于在大量字符串中快速查找特定字符串或判断两个字符串是否相等

字符串哈希的基本思想是将字符串视为一个较大的数字,然后使用哈希函数将其转换为一个较小的、固定长度的整数。这个哈希值可以作为字符串的"指纹",用于快速比较字符串是否相等或用于在哈希表等数据结构中进行快速查找。

既然要保证这个哈希值可以作为某个字符串的“指纹”,那就证明这个哈希值是独一无二的,不存在两个不同的字符串有相同的哈希值的情况。

那么现在来介绍三种求哈希值的方法。

基本每种方法都要使用到base 和 mod,全部它们两都要是素数,base用于进制转换,mod用与取模,一般这样得到的一个数出重的概率是相当低的,当然base和mod要尽可能大,不然会出重概率会提升。

2.自然溢出哈希

先来看一下自然溢出法的代码公式。

ull Hash(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=ans*base+(ull)s[i];
	}
	return ans; 
}

这里的base我们给它定义的是131,也是符合素数的要求。

公式:

base=素数,ull=unsigned long long

ans=ans*base+(ull)s[i]

3.单哈希

其实单哈希和自然溢出哈希差不多,就是单哈希多了一个取模操作。

ull Hash(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=(ans*base+(ull)s[i])%mod;
	}
	return ans; 
}

公式:

base=131,mod=2123704401301,ull=unsigned long long

ans=(ans*base+(ull)s[i])%mod

4.双哈希

既然是叫双哈希了,那就是两个单哈希组成的咯。

注意:里面的base1,base2,mod1,mod2都不一样,但是都是素数。

ull Hash1(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=(ans*base1+(ull)s[i])%mod1;
	}
	return ans; 
}
ull Hash2(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=(ans*base2+(ull)s[i])%mod2;
	}
	return ans; 
}

这时候我们可以给映射的整数数组搞一个结构体,里面放两个参数。

公式:

base1=131,base2=171,mod1=2123704401301,mod2=2123704401307

ans1=(ans1*base1+(ull)s[i])%mod1

ans2=(ans2*base2+(ull)s[i])%mod2

5.例题分析

例题链接

数据输入:

5
abc
aaaa
abc
abcc
12345

1.自然溢出哈希AC代码

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const ull base=131;
const ull mod=212370440130137957ll;
ull a[200100];
int n;
string s[200100];
ull Hash(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=ans*base+(ull)s[i];
	}
	return ans; 
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
	for(int i=0;i<n;i++){
		a[i]=Hash(s[i]);
	}
	sort(a,a+n);
	ull ans=1;
	for(int i=1;i<n;i++){
		if(a[i]!=a[i-1])
		ans++;
	}
	cout<<ans<<endl;
	return 0;
} 

2.单哈希AC代码

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const ull base=131;
const ull mod=1919372184011;
ull a[200100];
int n;
string s[200100];
ull Hash(string k)
{
	ull ans=0;
	for(int i=0;i<k.size();i++){
		ans=(ans*base+(ull)k[i])%mod;
	}
	return ans; 
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
	for(int i=0;i<n;i++){
		a[i]=Hash(s[i]);
	}
	sort(a,a+n);
	ull ans=1;
	for(int i=1;i<n;i++){
		if(a[i]!=a[i-1])
		ans++;
	}
	cout<<ans<<endl;
	return 0;
} 

3.双哈希AC代码

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const ull base1=131;
const ull base2=171;
const ull mod1=2123704401301;
const ull mod2=2123704401307;
struct node{
	ull x,y;
}a[200010];
int n;
string s[200100];
ull Hash1(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=(ans*base1+(ull)s[i])%mod1;
	}
	return ans; 
}
ull Hash2(string s)
{
	ull ans=0;
	for(int i=0;i<s.size();i++){
		ans=(ans*base2+(ull)s[i])%mod2;
	}
	return ans; 
}
bool cmp(node a,node b)
{
	return a.x+a.y<b.x+b.y; 
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s[i];
	}
	for(int i=0;i<n;i++){
		a[i].x=Hash1(s[i]);
	}
	for(int i=0;i<n;i++){
		a[i].y=Hash2(s[i]);
	}
	sort(a,a+n,cmp);
	ull ans=1;
	for(int i=1;i<n;i++){
		if(a[i].x!=a[i-1].x&&a[i].y!=a[i-1].y)
		ans++;
		
	}
	cout<<ans<<endl;
	return 0;
} 

6.总结

运行速度:

自然溢出哈希>单哈希>双哈希

安全性:

双哈希>单哈希=自然溢出哈希

当然精准度也与base和mod定义的大小有关。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE开发01--part 1:创建游戏模式、角色、控制器

1&#xff0c;右键选择新建C类 2&#xff0c;选择GameModeBase 3&#xff0c;随便命名&#xff0c;类的类型-->选择&#xff1a;公共&#xff1b; 这个选项会把.h和.cpp文件分开&#xff0c;方便我们查看与修改代码。 4.打开 VS 编辑器&#xff0c;查看我们刚刚创建得两文件…

机器学习 day38(有放回抽样、随机森林算法、XGBoost)

有放回抽样 有放回抽样和无放回抽样的区别&#xff1a;有放回可以确保每轮抽取的结果不一定相同&#xff0c;无放回则每轮抽取的结果都相同 在猫狗的例子中&#xff0c;我们使用”有放回抽样“来抽取10个样本&#xff0c;并组合为一个与原始数据集不同的新数据集&#xff0c;虽…

2.1_2 进程的状态与转换

2.1_2 进程的状态与转换 &#xff08;一&#xff09;进程的状态——创建态、就绪态 进程正在被创建时&#xff0c;它的状态是“创建态”&#xff0c;在这个阶段操作系统会为进程分配资源、初始化PCB。 当进程创建完成后&#xff0c;便进入“就绪态”&#xff0c;处于就绪态的进…

如何在Windows系统中检测和结束运行中的程序(任务管理器显示运行程序可能有bug)

如何在Windows系统中检测和结束运行中的程序 在Windows系统的日常使用和管理过程中&#xff0c;我们经常需要检测某个程序是否正在运行&#xff0c;并在必要时结束它。本文将详细介绍如何在Windows系统中检测运行中的程序&#xff0c;并提供多种方法来结束这些程序。 检测运行…

Vue思维导图,复习+预习,其中有些已经弃用了,下期总结下

1、学前了解 2、基础知识 3、组件相关语法 4、高级语法 5、compositionAPI 6、配套工具

QML 高效开发之加载方式

背景 日常使用 QML开发软件过程中&#xff0c;默认使用 qrc 存在开发效率慢问题&#xff0c;比如每次修改界面内容后需要先构建才能看到实际效果&#xff0c;尤其在频繁调试界面样式时显得更繁琐 原理 Qt 中的资源分为两类&#xff0c;编译型和外部二进制资源 编译型资源每…

⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)

105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,…

朋友圈程序全开源版源码,附带系统搭建教程

前台一键发布图文&#xff0c;视频&#xff0c;音乐。发布内容支持定位或自定义位置信息。支持将发布内容设为广告模式消息站内通知或邮件通知。支持其他用户注册,支持其他用户发布文章,管理自己的文章。拥有丰富的后台管理功能&#xff0c;一键操作。安装环境 Nginx ≥1.22 …

stm32——hal库学习笔记(外部中断)

一、什么是中断&#xff1f;&#xff08;了解&#xff09; 打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断 中断的作用和意义 中断的意义&#xff1a;高效处理紧急程序&#xff0c;不会一直占用CPU资源 S…

Android14 InputManager-InputManagerService环境的构造

IMS分为Java层与Native层两个部分&#xff0c;其启动过程是从Java部分的初始化开始&#xff0c;进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start&#xff08;&#xff09;函数完成启动 同其他系统服务一样&#xff0c;IMS在SystemServer中的ServerT…

浅谈加密算法(对称加密、非对称加密、混合加密、数字签名、哈希函数)

1、对称加密 对称加密只有一个密钥&#xff0c;直接使用这一个密钥对信息进行加密或解密。这样子就使得对称加密解密十分高效&#xff0c;计算量也相较于非对称加密小很多&#xff0c;适合有大量数据的场合。 密钥只有一个且他一定不能泄漏。由此分发密钥&#xff0c;讲这个密钥…

聚合支付,聚合系统,聚合程序或将成为主流

支付市场的变化对用户、代理商和运营商产生了重大影响。 随着政策监管的日益严格&#xff0c;支付行业逐渐朝着标准化和合理化的方向发展&#xff0c;日益增强其安全性。在这个背景下&#xff0c;聚合平台已经成为未来支付行业发展的重要趋势。特别是在“一机一码”政策实施后&…

三防平板丨平板终端丨加固平板丨户外勘测应用

随着科技的不断发展&#xff0c;现代勘测业也在不断升级。相较于传统的勘测设备&#xff0c;三防平板在户外勘测中有着广泛的应用。那么&#xff0c;三防平板在户外勘测中究竟有哪些优势呢&#xff1f; 首先&#xff0c;三防平板具备极强的防水、防尘、防摔能力。在野外勘测中&…

MyBatis---初阶

一、MyBatis作用 是一种更简单的操作和读取数据库的工具。 二、MyBatis准备工作 1、引入依赖 2、配置Mybatis(数据库连接信息) 3、定义接口 Mapper注解是MyBatis中用来标识接口为Mapper接口的注解。在MyBatis中&#xff0c;Mapper接口是用来定义SQL映射的接口&#xff0c;通…

十分钟利用springboot写电商支持多种优惠券规则,使用策略模式替代大量的if-else

前言 在开发电商折扣模块的时候经常会碰到各种优惠规则&#xff0c;那么就会碰到很多条件判断&#xff0c;冗余各种if-else的代码使得维护困难&#xff0c;此时就可以用策略模式来解决&#xff0c;替代大量的冗余判断条件代码&#xff0c;精简代码结构。 策…

建筑行业的重要工具—— 智慧工地管理平台(java源码)

系统定义&#xff1a; 智慧工地管理平台系统是一种集成了先进的信息技术、物联网技术、移动互联网技术等多种技术的工地管理系统。它能够对工地的整个生命周期进行全面的管理&#xff0c;包括工地的规划、设计、施工、监控、验收等各个环节。通过信息化手段&#xff0c;提高了工…

拯救者Legion Y9000K 2021H(82K6)原厂oem预装Win11系统镜像

lenovo联想拯救者Y9000K(82K6)原装出厂Windows11系统安装包下载&#xff0c;恢复出厂开箱状态 链接&#xff1a;https://pan.baidu.com/s/1DGWU7gctJerff6LJrgHD5w?pwdrbs5 提取码&#xff1a;rbs5 原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office…

C++从入门到精通 第十四章(STL容器)【下】

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

基础数据结构与相关C++ STL容器

文章目录 数组arrayvector 栈和队列dequestackqueue 堆heappriority_queue 链表listforward_list 树setmapmultisetmultimap 哈希表unordered_setunordered_mapunordered_multisetunordered_multimap 图 数组 array 不开口的连续线性空间&#xff0c;支持随机访问。 array是…

【C->Cpp】由C迈向Cpp(4)

目录 &#xff08;一&#xff09;内联函数 &#xff08;二&#xff09;关键字auto &#xff08;三&#xff09;范围for &#xff08;四&#xff09;nullptr 正文开始&#xff1a; &#xff08;一&#xff09;内联函数 宏定义&#xff1a; C的内联函数是在C语言宏的基础上提出…