浅谈字符串哈希 By cellur925
前言
蒟蒻最近在复习字符串算法...但正如之前所说,我OI太菜被关起来了,本蒟蒻只能从最简单的哈希入手了TAT。而别的dalao都在学习AC自动机/后缀数组等高到不知哪里去的算法qwq。
基本思想
映射。把一个任意长度的字符串映射为一个非负整数,要求冲突概率几乎为0。方法是把字符串看成$p$进制数,通常取$p$为131或13331,当然还有特殊情况,如[CTSC2014]企鹅QQ这道题,之后会解释这种情况。
基本操作
*****************采用unsigned long long存储哈希值和131的幂次***********************
一般情况下,我们都是预处理出字符串前缀子串的哈希值,如下。复杂度是$O(n)$的。
for(int i=;i<=len;i++)
f[i]=f[i-]*+ch[i];
//ch[]是字符数组
当然也可以边用边求啦qwq,主要用于带修改的情况,如[USACO15FEB]审查(黄金)Censoring (Gold),就不能预处理出来,因为随时可能会有删除字符的操作qwq。
调用一个字符串子串$S[l,r]$的哈希值。复杂度是$O(1)$的。$p$数组是131的幂次,可提前预处理出来,注意$p[0]=1$。以及注意$p$数组若需要预处理,一定处理到字符串的最大长度。
ull gethash(int l,int r)
{
return f[r]-f[l-]*p[r-l+];
}
如果我们想要得到同一个字符串中的两个子串拼接得到的串的哈希值?
从这个问题开始,我们并不需要死记硬背,而是切身的把字符串当做一个数,用进制的思想解决。举第一个栗子:
在[CTSC2014]企鹅QQ这道题中,我们每次都在枚举把哪一个位置的字符去掉,然后将这个字符左边的字符串和右边的字符串重新拼接成一个新的字符串。
假设我们现在有"$zsyasjttql$“这个字符串,我们现在删去第4个位置的“a”,欲得到“$zsysjttql$”,而且我们已经处理了所有前缀的哈希值。那么我们就可以用第一个子串的哈希值乘$131^{len-4}$,类似把一个数分开的操作,在加上第二个字符串的哈希值,就能得到新字符串的哈希值。
Warning?
$strlen$操作是$O(n)$的?所以尽量不要多次调用,而是一次解决。一不小心在循环里可能就会搞成$O(n^2)$的qwq.
$hash$是关键字啦qwqwq,还是尽量避讳的好。
例题
例1
LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)【Hash做法】By cellur925
例2
[CTSC2014]企鹅QQ
给 n 个字符串,如果两个字符串只有同一个位置的字符不相同,那
么称这两个字符串是相似的。
字符串的长度都相等,并且字符串两两不同。
求一共有多少对相似字符串。
n ≤ 30000; |Si| ≤ 200,时间限制 2 秒。
可以枚举删去字符的位置,然后再比较他们的哈希值。
Code
#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std;
typedef unsigned long long ull; int n,l,s;
long long ans;
char tmp[];
ull f[][],p[],tong[]; ull gethash(int u,int l,int r)
{
return f[u][r]-f[u][l-]*p[r-l+];
} int main()
{
p[]=;
scanf("%d%d%d",&n,&l,&s);
for(int i=;i<=n;i++)
{
scanf("%s",tmp+);
int len=strlen(tmp+);
for(int j=;j<=len;j++)
f[i][j]=f[i][j-]*+tmp[j],p[j]=p[j-]*;
}
for(int pos=;pos<=l;pos++)
{
for(int i=;i<=n;i++)
{
ull ha1=gethash(i,,pos-);
ull ha2=gethash(i,pos+,l);
tong[i]=ha1*p[l-pos]+ha2;
}
sort(tong+,tong++n);
int noww=;
for(int pos=;pos<=n;pos++)
if(tong[pos]==tong[pos-]) ans+=noww,noww++;
else noww=;
}
printf("%lld",ans);
return ;
}
总结
哈希还是很简单的知识,但是需要灵活运用。只要把字符串当做一个纯洁的数字,再按照数的方式构造乱搞就行了。虽然我不会别的高级字符串算法(逃),但是灵活使用哈希也可以补充智商不够没学过那么多算法的缺陷嘛(逃)
浅谈字符串哈希 By cellur925的更多相关文章
- 浅谈字符串Hash
浅谈字符串Hash 本篇随笔讲解Hash(散列表)的一个重要应用:字符串Hash. 关于Hash Hash是一种数据结构,叫做Hash表(哈希表),也叫散列表.关于Hash的实现,其实与离散化颇为类似 ...
- 浅谈一致性哈希(My转)
一致性哈希(Consistent hashing)算法是由 MIT 的Karger 等人与1997年在一篇学术论文(<Consistent hashing and random trees: d ...
- 浅谈欧拉函数 By cellur925
1.某神犇Blog 学了三遍的 欧拉函数φ--DEADFISH7 2.我要做一些补充o(* ̄▽ ̄*)o $φ(1)=1$: 公式有两种形式,一种有太多除法,实际可能会慢些.通用 对于任意$n$> ...
- 浅谈并查集 By cellur925【内含题目食物链、银河英雄传说等】
什么是并查集? 合并!查询!集合! 专业点说? 动态维护若干不重叠的和,支持合并查询的数据结构!(lyd老师说的) 数据结构特点:代表元.即为每个集合选择一个固定的元素,作为整个集合的代表,利用树形结 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 浅谈 js 字符串之神奇的转义
原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...
- 浅谈 js 字符串 trim 方法之正则篇
原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格 等 ...
- 浅谈 js 字符串 search 方法
原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...
- 浅谈python字符串存储形式
http://blog.csdn.net/zhonghuan1992 钟桓 2014年8月31日 浅谈python字符串存储形式 记录一下自己今的天发现疑问而且给出自己现有知识有的回答. 长话短说,用 ...
随机推荐
- c程序设计语言第一章2
练习1.13编写一个程序,打印输入中单词长度的直方图.水平方向的直方图比较容易绘制,垂直方向的直方图则要困难些 #include <stdio.h> #include <stdlib ...
- Photoshop 更改图片颜色
程序猿兼职美术的常常没有时间搞太多图片.我们能够一张图片更改主要颜色来到达目的.我知道的主要有2种方法,1是更改色相,2是替换颜色.直接用油漆桶仅仅能在异常简单的图片才干用. 1. 更改色相 ...
- 创建Vue项目的步骤
第一步: 对于要创建项目的工作目录,要先进性管理,命令:npm init -y 第二步: 初始化webpack 包,命令:vue init webpack 自定义名称 第三步: 在components ...
- crontab -e 定时任务中的 脚本文件 路径
crontab -l 57 */1 * * * python /home/data/crontab_chk_url/personas/trunk/plugins/spider/chk_url_stat ...
- 20170223-问题001,增强中的E消息 显示为 S模式消息,
MM01 的屏幕增强,里面写的 MESSAGE e056(z1) WITH '供应链计划(SCP) 储备物料与当期物料不能同时选择.'.可是现实出来是S 消息模式,这是为什么?系统转换了吗 ...
- hihocoder hiho一下 第二十六周 最小生成树一·(Prim算法)
题目1 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥 ...
- jQuery插件之ajaxFileUpload API文档
ajaxFileUpload是一个异步上传文件的jQuery插件. 语法:$.ajaxFileUpload([options]) options参数说明: 1.url 上传处理程序地址. 2,fil ...
- [Selenium] Android HTML5 中 Web Storage
在 HTML5 中,Web Storage 这个新特性可让用户将数据存储在本地的浏览器中.在早期的浏览器中可通过 cookies 来完成这个任务,但 Web Storage 会更加安全和高效,且 We ...
- 理解分布式id生成算法SnowFlake
理解分布式id生成算法SnowFlake https://segmentfault.com/a/1190000011282426#articleHeader2 分布式id生成算法的有很多种,Twitt ...
- CCRect 构造函数的几个参数解释
转自: http://blog.163.com/hzklclick_wy/blog/static/21550517520137139511839/ void CCRect::setRect(f ...