理论概念

这玩意一直都是个好东西,但是我总觉得玄学的一批。今天借着专题学习的劲头,把Hash好好梳理一下。

定义/作用

哈希这东西应该都不陌生。将复杂的信息映射到一个容易维护的值域之内。那么Hash函数就有点类似于一个映射关系。通过这个函数来产生一个关键值(Key),通过关键值与值(value)的对应关系,制作一个对应表。即哈希表(Hash table)。他可以实现通过Key快速的查找Value。

那么其最大作用也就显而易见。查重。也就是说,查找当前的值是否已经存在。难点在于,如何去产生这个对应关系?简单的映射关系是有相当的可能产生“两组不同的值生成同一个关键值”的错误(我们称其为哈希冲突)。如果哈希函数的设计太水,那么这个哈希冲突也就非常容易产生了。

整数(int)哈希举例

引用了一个对整数数组生成Hash的方法,这里只做举例。在本例中,不关心数组中数的序列问题。即只考虑数组内值不同为不同状态,如果值相同但顺序不同,我们仍认为他是同一状态。(会产生相同的关键值)

对于一组数,其乘积与其累加之和与任意较大质数P取模。

//这里是针对于某一个题目所引入的,所以具体原因会在下方的题目展示中阐释。

字符串哈希

定义与技巧

常用的字符串哈希分两类(没错,我觉得该分两类的!)

自然溢出式Hash与多重Hash。一般来讲,前者虽然发生哈希冲突的几率非常小,但总会被刁钻(诶嘿嘿)的出题人卡几个数据。是的,他们是具备能卡你自然溢出单哈希的能力的。所以稳妥起见,后者运用频率偏高一些。

什么是字符串哈希?就是把一个任意长度的字符串映射成一个非负整数,并且其冲突概率几乎为0

把字符串看作P进制数,并分配一个大于0的数值,代表每种字符。啥意思啊?比如a对应1,b对应2,c对应3。取一个固定的值M,求出该P进制数对于M的余数,作为该字符串的哈希值。一般来说,P取131或者13331,这样冲突几率就极低。一般M取264,也就是一个自然溢出的unsigned long long。就让你溢出,取代低效的取模运算。

这也就是第一类Hash。为了避免被卡,我们多取一些适当的P与M。(例如大质数),进行多组Hash运算。如果结果都相同,我们就认定这是一个相等的字符串。

性质

对没错!我觉得这是性质!!

有了以下两种性质,我们便可以做到在O(N)的时间内预处理所有前缀Hash值,并在O(1)的时间内完成查询任意字串的哈希值。

一、

对于任意新字符串S+C,他的Hash值就是

H(S+C)=(H(S)*P+Value[C])mod M

为什么?我们来进行一个简单的模拟。

例如,S="abc",C=“d”

S表示为P进制的数:1 2 3

H(S)=1*P2+2*P+3

H(S+C)=1*P3+2*P2+3*P+4=H(S)*P+4

这里可以把*P的操作视为在P进制下的左移运算。Value[c]是我们为c选定的代表数值。

二、

如果已知字符串S的Hash值为H(S),字符串S+T的Hash值为H(S+T),那么字符串T的Hash值

H(T)=(H(S+T)-H(S)*Plength(T)) mod M

那么我们继续之前的模拟。

例如,S="abc",C=“d”,T=“xyz”

S表示为P进制的数:1 2 3

S+T的P进制数为:1 2 3 24 25 26

H(S)=1*P2+2*P+3

H(S+T)=1*P5+2*P4+3*P3+24*P2+25*P+26

S在P进制下左移length(T)位:1 2 3 0 0 0

两者相减就是T表示为P进制数:24 25 26

H(T)=H(S+T)-(1*P2+2*P+3)*P3=24*P2+25*P+26

在题目中的Show Time

Snowflake Snow Snowflakes  POJ3349

等待补充

兔子与兔子 CH1401

由于目标题库被查表…等待恢复。

好文章 2015模拟题By nodgd

因为这是一个专题博文,所以我不会去仔细深究他没有涉及到哈希的原理。

在这道题中,我们可以枚举每一个长度为m的子串。那么一共会有n-m+1个长度为m的子串。我们将他们的哈希值分别取出来,然后再进行比对。如果相等,则忽略,否则ans++

我听说这道题用自然溢出哈希是翻车了的。故我贴这个题的目的,是想贴一下双哈希的大概样子。

#include<bits/stdc++.h>
#define N 200009
using namespace std;
char a[N];
long long ans, n, m,hs2[N], len1[N], len2[N], hs1[N],p1=131,p2=13331,mod1=1000000009,mod2=1000000007;
struct hah{long long h1, h2;
}hash[N];
long long cmp(hah x, hah y){if (x.h1 == y.h1)    return x.h2 < y.h2; return x.h1 < y.h1;
}
void prepare(){len1[0] = 1, len2[0] = 1;for (int i = 1; i <= n; i++){hs2[i] = (hs2[i - 1] * p2 + (a[i] - 'a' + 1)) % mod2;//性质1 hs1[i] = (hs1[i - 1] * p1 + (a[i] - 'a' + 1)) % mod1;len1[i] = (len1[i - 1] * p1) % mod1, len2[i] = (len2[i - 1] * p2) % mod2;//预处理了p的前缀和 次方
    }
}
void gethash(long long l, long long r, long long oi){hash[oi].h2 = (hs1[r] - hs1[l - 1] * len1[r - l + 1] % mod1 + mod1) % mod1;//性质2 hash[oi].h1 = (hs2[r] - hs2[l - 1] * len2[r - l + 1] % mod2 + mod2) % mod2;
}
int main(){cin>>n>>m;cin >> a + 1;prepare();for (int i = 1; i <= n - m + 1; i++)gethash(i, i + m - 1, i);//枚举每个子串并取其哈希值 sort(hash + 1, hash + n - m + 2, cmp);for (int i = 1; i <= n - m + 1; i++)if (hash[i].h2 == hash[i + 1].h2 && hash[i].h1 == hash[i + 1].h1)    continue;else ans++;cout<<ans;
}

转载于:https://www.cnblogs.com/Uninstalllingyi/p/11191045.html

基本数据结构—Hash哈希相关推荐

  1. 「Redis数据结构」哈希对象(Hash)

    「Redis数据结构」哈希对象(Hash) 文章目录 「Redis数据结构」哈希对象(Hash) 一.概述 二.编码 ZipList HashTable 三.编码转换 一.概述 Redis中hash对 ...

  2. 数据结构 Hash,哈希冲突,哈希聚集,BloomFilter,分布式一致性hash

    海量数据去重Hash与BloomFilter, Bitmap 顺序访问的数据结构 hash函数 冲突 hash聚集 布隆过滤器 hyperloglog -- Redis 分布式一致性Hash 顺序访问 ...

  3. Hash+哈希表+HashMap+HashSet

    Hash+哈希表+HashMap+HashSet 哈希算法,是一类「算法」. 哈希表(Hash Table),是一种「数据结构」. 哈希函数,是支撑哈希表的一类「函数」. Map是映射/地图的意思,在 ...

  4. [Redis6]常用数据结构_Hash哈希

    Hash哈希 简介 Redis hash 是一个键值对集合. Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象. 类似Java里面的Map< ...

  5. Hash哈希(hashCode、HashSet 、HashMap)

    文章目录 Hash HashMap类 存储 HashMap的长度 Java的hashCode()方法 hashCode() 与 equals() 的关联 情况1(不重写hashCode()和equal ...

  6. 什么是Hash哈希(散列表)

    什么是Hash哈希(散列表) 相信学计算机的各位都绝对听过Hash哈希(散列表),有些人认为Hash是一种算法,有人认为它是一种数据结构,其实这些说法都不算太准确.其实hash是一类算法的集合,或者说 ...

  7. C++八股文分享---数据结构其二---哈希表

    C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...

  8. 图书馆管理系统(C、数据结构、哈希表、文件IO)

    目录 技术路线 实现效果展示 ​程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...

  9. redis 中 Hash哈希介绍 及常用命令 (附有示例)

    目录 一.Redis中Hash介绍 二.常用命令 三.示例 hset hget hmset   .. hexists hkeys hvals hincrbu hsetnx 四.redis中Hash底层 ...

最新文章

  1. 【带你玩转主题模型Topic Model】—— 之 利用sklearn 实现Latetnt Dirichlet Allocation(LDA)主题模型
  2. 第一百零二节,JavaScript函数
  3. 全民大数据时代已来 阿里数加平台详解
  4. BootStrap导航栏的使用
  5. JS根据文本框内容匹配并高亮显示
  6. 笔记-网页内嵌Google地图与地理位置模拟
  7. ubuntu14.04 安装 pyv8
  8. JVM-JConsole:Java监视与管理控制台(windows)
  9. Direct3D 11 Devices 之 Using Direct3D 11 feature data to supplement Direct3D feature levels
  10. GMT格林威治时间标准时北京时间
  11. 64位计算机装32位系统,32位装64位系统教程
  12. JavaSE:抽象(abstract)
  13. 六、hibernate表与表之间的关系(多对多关系)
  14. java打桩_使用JUnit4与JMockit进行打桩测试
  15. Elliptical Grid Mapping(椭圆映射法)
  16. 飞信免费发短信API
  17. java 数字翻译成英文_java 英文翻译成数字
  18. 杭电4510—小Q系列故事—为什么时光不能倒流
  19. web移动端开发-将网站分享朋友圈、微信空间、朋友圈功能
  20. 数据结构与算法(陈越版)第五讲 (树下)树的应用——集合及其运算

热门文章

  1. SQL Server数据库表锁定原理以及如何解除表的锁定转
  2. 3-unit1 IPv6网络的管理
  3. 《深入解析Android 虚拟机》——第1章,第1.3节编译Android源码
  4. Asp将查询结果导出到excel里
  5. Css中Position属性的含义
  6. 天天用 Spring,bean 实例化原理你懂吗?
  7. 互联网人的《三十而已》:裸辞,催婚,职业瓶颈,逃离北上广深......
  8. 大型网站架构演进的五大阶段盘点
  9. 这样学习正则表达式就轻松了!
  10. 演化:这五年里,我们对架构师职责的思考与定位