浅谈字符串Hash

本篇随笔讲解Hash(散列表)的一个重要应用:字符串Hash。

关于Hash

Hash是一种数据结构,叫做Hash表(哈希表),也叫散列表。关于Hash的实现,其实与离散化颇为类似。就是把若干的复杂的信息映射到一个比较容易维护的值域去。具体的实现方式是散列函数,即Hash函数,其原理是对于一个数据,选取一个关键键值\(k\),那么这个数据在Hash表中的位置就是\(f(k)\)。那么这个对应关系(\(f()\))就是哈希函数。

哈希冲突

因为我们只是定义了一个\(f()\)作为哈希函数,并没有定义这个\(f()\)到底是什么样的函数。所以显然地,可能会出现一个函数\(f(k)\),使得两个不同的\(k(k_1\not=k_2)\)而出现函数值相等的情况\(f(k_1)=f(k_2)\)(比如二次函数)。这种情况被称作哈希冲突。导致答案错误。

关于字符串Hash

字符串哈希就是在字符串上进行哈希。字符串哈希的用处是快速判断两个字符串是否相等

一个简单的思想:将一个字符串转化为一个整数,这样,只需要比较整数相不相等就可以判断这个串是否重复出现过(不考虑哈希冲突)。

但是这个思想不考虑哈希冲突,不代表我们实现的时候也肯定不会出现哈希冲突。那么,我们当然希望我们哈希的东西(哈希映射,散列函数)是一个单射。

那么,我们用什么方法来避免哈希冲突呢?

自然溢出

给定一个字符串\(S=s_1s_2s_3\cdots s_n\),我们规定:\(f(x)=x-'a'+1\).

那么,自然溢出的哈希公式可以如此这么表示:
\[
hash[i]=hash[i-1]*p+f(i)
\]
注意,这里的哈希数组是\(unsigned\, long\, long\)范围的,所以可以通过自然溢出而自动取模\(2^{64}-1\)。

单Hash法

单Hash法的哈希公式可以这么表示:
\[
hash[i]=(hash[i]*p)+f(i)\%mod\quad (p<mod)
\]
显然,\(mod\)越小越容易冲突,所以我们把\(p,mod\)都尽量取大即可。

这种方法仍然存在哈希冲突的概率,只不过特别低。实际运用的时候可以使用这种方法。除非你RP低到一定境界,否则不会被卡掉。

例如:

\(p=13,mod=101\),对\(abc\)进行如上所示的\(hash\)。

\(hash[0]=1\)(从0开始计算)

\(hash[1]=15\)

\(hash[2]=97\)

那么97就是\(abc\)的hash值。

双hash法

hash一遍可能还会出现冲突,那我hash两遍。这就是双Hash法。

开一个二元组,用两个不同的\(mod\)来分别\(Hash\),得到的两个结果存进二元组,作为哈希的结果。

同理,你还可以开一个结构体,多哈希几遍(强迫症患者)(滑稽.jpg)

子串Hash

字符串子串是个常见的问题,变式很多。

但是,显然的是,如果我们求出了一个大串的hash,就能以\(O(1)\)的时间求解其子串的哈希值。

来让我们解释一下这个“显然”的含义:

\(hash[1]=s1\)
\(hash[2]=s1∗p+s2\)
\(hash[3]=s1∗p2+s2∗p+s3\)
\(hash[4]=s1∗p3+s2∗p2+s3∗p+s4\)
\(hash[5]=s1∗p4+s2∗p3+s3∗p2+s4∗p+s5\)
现在展示的是1-5的哈希。

如果我们要求s3s4的哈希,容易得出(根据哈希公式):\(s_3\times p+s_4\)。我们把\(hash[4],hash[2]\)进行消元处理的话,就能将结果中带有\(s_1,s_2\)的系数消掉,而这个操作只需要乘上\(p^2\)即可。

那么:
\[
hash[4]-hash[2]\times p^{4-3+1=2}
\]
那么我们处理出通项公式:
\[
hash[i]-hash[j-1]\times p^{i-j+1}
\]
取模的时候为了防止减法运算出现负数,还要做如下处理:
\[
hash=((hash[i]-hash[j-1]\times p^{j-i+1})\%mod+mod)\%mod
\]
这就完事了。

浅谈字符串Hash的更多相关文章

  1. 【字符串算法1】 再谈字符串Hash(优雅的暴力)

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...

  2. 浅谈字符串哈希 By cellur925

    前言 蒟蒻最近在复习字符串算法...但正如之前所说,我OI太菜被关起来了,本蒟蒻只能从最简单的哈希入手了TAT.而别的dalao都在学习AC自动机/后缀数组等高到不知哪里去的算法qwq. 基本思想 映 ...

  3. 浅谈NTLM Hash

    认识Windows Hash 早期SMB协议在网络上传输明文口令.后来出现LAN Manager 挑战/响应验证机制(LM),其很容易破解,因此微软提出了WindowsNT挑战/响应验证机制(NTLM ...

  4. 浅谈一致性Hash原理及应用

    在讲一致性Hash之前我们先来讨论一个问题. 问题:现在有亿级用户,每日产生千万级订单,如何将订单进行分片分表? 小A:我们可以按照手机号的尾数进行分片,同一个尾数的手机号写入同一片/同一表中. 大佬 ...

  5. 浅谈一致性hash

    相信做过互联网应用的都知道,如何很好的做到横向扩展,其实是个蛮难的话题,缓存可横向扩展,如果采用简单的取模,余数方式的部署,基本是无法做到后期的扩展的,数据迁移及分布都是问题,举个例子: 假设采用取模 ...

  6. $.ajax()方法详解 ajax之async属性 【原创】详细案例解剖——浅谈Redis缓存的常用5种方式(String,Hash,List,set,SetSorted )

    $.ajax()方法详解   jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为Str ...

  7. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  8. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  9. 浅谈 js 字符串 trim 方法之正则篇

    原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格   等 ...

随机推荐

  1. WPF 字体设置

    原文:WPF 字体设置 WPF 主界面 更换字体 可全局 但是有的时候有的窗体 字体还是没变 可以做全局样式 <Window x:Class="CLeopardTestWpf.Main ...

  2. C语言中,关于排序的问题(输入n个数,输出最大的那个)

    int n,max=0,t; scanf("%d",&n); int a[n],i,k;  //这个a[n]必须要在输入n的值之后才能定义,不然定义不成. for(i=1; ...

  3. flag 履行我的flag

    以后数组开小就不吃饭!!!!!! 上午考试不吃午饭 下午考试不吃晚饭 晚上考试不吃早饭 我以后还能吃饭吗 11.12距离csp-s还有2天,我的数组开小了,履行承诺,不吃饭了

  4. settings.py相关配置

    INSTALLED_APPS   #配置项目绑定的应用 TEMPLATES   #配置项目使用的模板引擎 DATABASES   #设定绑定的数据库 TIME_ZONE   #设定时区,时区的设定可能 ...

  5. 详解JAVA8Stream API {全}

    1: 概述 1.1 优势 1.2 与传统迭代器的区分 1.3 流的操作类型分为两种: 2:流的构造与转换 2:1 常见构造 2.2: 三大包装类型的构造 2.3 并行流的规则输出 2.4 流的转换 3 ...

  6. python3中的数字类型

    今天在学校机房刷python题时发现自己对python中的数字类型不理解,回寝室后百度一下. 现在做一个总结. python中的数字类型有: 整数,布尔值,复数,科学计数法,浮点数 1,整数,大小没有 ...

  7. 安装v2sora@y

    v2r@y安装 1. 安装nginx 这儿使用tengine进行安装, 可以看以前的博客 1.1) 注意带 http_v2 编译 ./configure --with-http_v2_module 不 ...

  8. 使用zabbix监控oracle的后台日志

    本文将介绍如何使用zabbix监控oracle的后台日志,当oracle后台日志出现“ORA-”或“Error”时,第一时间将该信息报警出来 zabbix agent端 以下所有操作均用root执行 ...

  9. EF中获取当前上下文的表名

    EF在处理并发上并不是很好,很多时候我们需要手动写sql操作数据库.但是在基类中我们如何获取当前服务仓储操作的表呢? 使用正则是其中一种解决办法 Repository.Table是一条查询语句,通过t ...

  10. 资深程序员:学Python我推荐你用这几款编辑器

    Python使用什么编辑比较好,Python编辑器推荐 各位 Pythoner 好啊!在这个烦躁的时代,相聚就是缘分,很高兴各位 Pythoner 能相聚于此,希望接下来的路,我们一起走下去,使用 P ...