RK哈希(Rabin_Karp 哈希)
Rabin_Karp 哈希
通过比较hash值是否相等来比较每个字符串是否相等
有概率出错(很小)
字符串x1,x2,x3……xk
基底e;模数mo;
hash=(xk*e^0+xk-1*e^1+......+x1*e^k-1)mod mo
注意:
①字符映射到数字不要映射到0
②基底e>字符种类数
③据说mo数为大素数出错概率小
mo=1000000007(存int64)
mo=666623333
递推建hash:
初始条件:hash[1]=x1;
递推式:hash[i]=(hash[i-1]*e+xi)mod mo;
区间hash:
对于任意关于x的子串xi-xj
hash[i,j]=(xj*e^0+xj+1*e^1+......+xi*e^j-i)mod mo;
O(n)的算法
hash[i,j]=(hash[j]-hash[i-1]*e^(j-i+1) mod mo+mo)mod mo
O(1)的算法
1.子串排序 sort.exe
【题目描述】给出一个长为n的字符串S,和一个数字m,记ssi表示从S的第i位开始、长度为m的子串。如,当S="abcab",m=2时,ssi的值分别为:
ss1="ab"
ss2="bc"
ss3="ca"
ss4="ab"
ss5="b"
你需要把ss1~ssn这n个字符串排序成字典序不降的形式。一开始,ss1~ssn这n个字符串排成一行;你每次只可以交换相邻两个字符串的位置。如,把上述ss1~ss5排好序的一种方案是:
⑴原序列:"ab", "bc", "ca", "ab", "b"
⑵交换第3和第4个串:"ab", "bc", "ab", ca", "b"
⑶交换第2和第3个串:"ab", "ab", "bc", ca", "b"
⑷交换第4和第5个串:"ab", "ab", "bc", b", "ca"
⑸交换第3和第4个串:"ab", "ab", "b", bc", "ca"
并且,上述方案是交换次数最少的方案。
你的任务就是编程求出最少的把所有子串排成字典序不降的形式的交换次数。
NOIP怎么可能会考后缀数组╮(╯_╰)╭
【输入格式】第一行包含两个整数n和m;
第二行包含一个长为n的字符串S。S只由小写字母组成。
【输出格式】一行,包含一个整数,表示最小的交换次数。
【样例输入】
5 2
abcab
【样例输出】4
【样例解释】样例数据就是题目描述中的例子。
【数据范围】
对于20%的数据,有n<=10;
对于40%的数据,有n<=100;
对于60%的数据,有n<=5000;
另有10%的数据,有m<=5;
另有10%的数据,字符串S是完全随机生成的;
对于100%的数据,有1<=m<=n<=50000
【解】注意直接存字符串+逆序对70分爆空间
●如果不是排字符串而是排数字?
●给出长为n的数字序列,只能交换相邻的元素,问最少交换几次变成不降?
●经典问题–求逆序对数
●证明:
交换相邻两个元素(左大右小)正好减少一对逆序对;
没必要交换左小右大的元素;
排好序的序列逆序对数为0。
●程序实现:归并排序
◎归并排序时比较两个数字的大小 à 归并排序时比较两个字符串的字典序大小
◎决定两个字符串字典序大小的是从左到右第一位不相同的字符
◎二分+哈希找到第一位不相同的位
◎数字O(1)比较大小 à 字符串O(logn)比较大小
◎归并排序O(nlogn),总复杂度O(nlog2n)
const mo=;
maxn=;
var f,s,tmp:array[..maxn]of longint;
n,m,i,ans,e:longint;
hash,pow:array[..maxn]of int64;
t:array[..]of longint;
ch:char;
function pd(i,j:longint):boolean;
var l,r,mid:longint;
hsi,hsj:int64;
begin
if i=j then exit(true);
l:=; r:=m+;
if n-j+<r then r:=n-j+;
if n-i+<r then r:=n-i+;
while r-l> do begin
mid:=(l+r) div ;
hsi:=hash[i+mid-]-hash[i-]*pow[mid]mod mo;
if hsi< then hsi:=hsi+mo;
hsj:=hash[j+mid-]-hash[j-]*pow[mid]mod mo;
if hsj< then hsj:=hsj+mo;
if hsi=hsj then l:=mid else r:=mid;
end;
if l=m then exit(true);
exit(s[i+l]<s[j+l]);
end;
procedure msort(l,r:longint);
var m,i,j,k:longint;
begin
if l=r then exit;
m:=(l+r)>>;
msort(l,m);
msort(m+,r);
i:=l;j:=m+;k:=l;
while (i<=m) and (j<=r) do begin
if pd(f[i],f[j]) then
begin t[k]:=f[i];inc(i);inc(k);end
else begin t[k]:=f[j];inc(j);inc(k);
ans:=ans+m-i+;//求逆序对的个数
end;
end;
while i<=m do begin
t[k]:=f[i];inc(i);inc(k);end;
while j<=r do begin
t[k]:=f[j];inc(j);inc(k);end;
for i:=l to r do f[i]:=t[i];
end;
begin
assign(input,'sort.in');reset(input);
assign(output,'sort.out');rewrite(output);
readln(n,m);
e:=;
pow[]:=;
hash[]:=;
for i:= to n do pow[i]:=pow[i-]*e mod mo;
for i:= to n do begin
read(ch);
s[i]:=ord(ch)-;
hash[i]:=(hash[i-]*e+s[i])mod mo;
f[i]:=i;
end;
s[n+]:=;
msort(,n);
writeln(ans);
close(input);close(output);
end.
2.找循环节 find.exe
如果一个字符串是以一个或者一个以上的长度为k的重复字符串所连接成的,那么这个字符串就被称为周期为k的字符串。例如,字符串”abcabcabcabc”周期为3,因为它是由4个循环”abc”组成的。它同样是以6为周期(两个重复的”abcabc”)和以12为周期(一个循环”abcabcabcabc”)。
写一个程序,读入一个字符串,并测定它的最小周期。
【输入格式】一个最长为 100 50000 的没有空格的字符串。(加点小小的难度,用上面知识求解)
【输出格式】一个整数表示输入的字符串的最小周期。
输入输出样例:
| PERIODIC.IN HoHoHo | PERIODIC.OUT 2 | 
【题解】
这道题求的是字符串算法给定一个字符串A,求最短的字符串B,使得A是若干个B连接而成的字符串的前缀,样例:若A=abcabcab则B=abc.(输出循环节长度3)
算法1:暴力n^2(能过len=100的点)
算法2:kmp(好像难了一点)不会qwq! O(n)
算法3:RK哈希(Rabin-Karp哈希):简单一点。。。O(n log n)
方法:
- 枚举循环节长度L
- 用哈希判断A[1…L],A[L+1…2L],A[2L+1…3L]……是否相等
- 最后一个循环节长度可能不足L,特殊判断
lalalalala~~
Answer:https://paste.ubuntu.com/25330495/
RK哈希(Rabin_Karp 哈希)的更多相关文章
- 哈希,哈希表,哈希Map
		数组: 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1):数组的特点是:寻址容易,插入和删除困难: 链表: 链表存储区间离散,占用内存比较宽松,故空间复杂 ... 
- PAT 甲级 1047 Student List for Course (25 分)(cout超时,string scanf printf注意点,字符串哈希反哈希)
		1047 Student List for Course (25 分) Zhejiang University has 40,000 students and provides 2,500 cou ... 
- 【 哈希和哈希表】Three Friends【进制哈希】
		Three Friends 传送门:链接 (UPC)或 链接(大视野) 题目描述 Three friends like to play the following game. The first f ... 
- [PHP内核探索]PHP中的哈希表
		在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据 ... 
- [基础技能] 安全技术——哈希算法密码破解之彩虹表(Rainbow Table)学习
		1.基础知识 刚刚学习过数字签名的相关知识,以及数字签名的伪造技术,而伪造数字签名归根结底就是密码破解的一个过程,然而直接破解的速度是非常缓慢的,所以有人想出一种办法,直接建立出一个数据文件,里面事先 ... 
- 简单的哈希表实现 C语言
		简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ... 
- Memcached 笔记与总结(8)Memcached 的普通哈希分布算法和一致性哈希分布算法命中率对比
		准备工作: ① 配置文件 config.php ② 封装 Memcached 类 hash.class.php,包含普通哈希算法(取模)和一致性哈希算法 ③ 初始化 Memcached 节点信息 in ... 
- 哈希(Hash)与加密(Encrypt)的基本原理、区别及工程应用
		0.摘要 今天看到吉日嘎拉的一篇关于管理软件中信息加密和安全的文章,感觉非常有实际意义.文中作者从实践经验出发,讨论了信息管理软件中如何通过哈希和加密进行数据保护.但是从文章评论中也可以看出很多朋友对 ... 
- Java中的哈希
		Java中的哈希 前言 在开发中经常用到HashMap.HashSet等与哈希有关的数据结构,一直只知道这些哈希的数据结构不保证顺序,不清楚具体什么情况.所以在这里大致总结一下. Java的Has ... 
随机推荐
- HBase启动时报错:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1.8.0_152/bin/java
			今天在启动HBase时发现如下错误:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1. ... 
- [python]记录Windows下安装matplot的经历
			最近学习在看<机器学习实战>一书,第二章的时候要用到Natplotlib画图,于是便开始安装Matplotlib.本文所用到的所有安装包都可以在文末的链接中找到. 首先从Matplotli ... 
- P问题,NP问题,NPC问题,NP-hard问题
			1.P问题:一个问题能找到一个在多项式时间里解决他的算法 多项式时间(o(1),o(lgn),o(n的a次方)) 非多项式时间 o(a的n次方) o(n!) 2.NP问题:在多项式时间找不到问题的解 ... 
- JavaScript快速入门-ECMAScript语句
			JavaScript语句(if.for.for in.do...while.while.break.continue.switch) 一.if语句 if (condition) statement1 ... 
- docker之compose 编排项目
			一.docker-compose 的介绍 docker-compose是一种容器编排工具,可以将多个docker容器关联部署.通过yaml文件,可以描述应用的架构,如使用什么镜像.数据卷.网络.绑定服 ... 
- 这可能是最详细的Python文件操作
			删除 # ==================删除==================# 只能删除文件,若为目录则报错# 若文件正在使用,Windows下会直接报错,Linux下会在目录表中删除记录, ... 
- Scrapy的日志等级和请求传参
			日志等级 日志信息: 使用命令:scrapy crawl 爬虫文件 运行程序时,在终端输出的就是日志信息: 日志信息的种类: ERROR:一般错误: WARNING:警告: INFO:一般的信息: ... 
- SVN基础操作
			SVN基础操作 安装 #大多数Linux版本自带svn svn --version #如果没有安装可用yum安装 yum install subversion 生命周期 创建版本库 检出 更新 执行变 ... 
- 浅谈SVG(可缩放的矢量图形)
			前一段项目中用到了svg图片就和其他的元素一样 直接引用就可以展示在页面上,因为项目紧张没有仔细的研究,最近在扩展自己的基础知识,偶然看到了这个东西,于是总结了一些博客园中关于这个svg的基础知识,只 ... 
- 《杜增强讲Unity之Tanks坦克大战》1-准备工作
			0.案例介绍 0.1开始界面 点击Play Now 进入游戏界面 左边的坦克使用ws控制前后移动,ad键左右旋转,空格键开火 右边的坦克使用方向键上下控制前后移动,方向键左右键实现左右旋转 ... 
