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 ...
随机推荐
- 编译最新的SQLite 3.8.4.3为一个DLL
SQLite是一个小型数据库.特别适合于client应用程序使用,它的众多优点就不多说了.有兴趣的去搜索. 话说使用吧. 我们要使用.就须要调用它.如今一步一步来. 第一步:上SQLite官网http ...
- 使用Highcharts生成折线图_at last
//数据库数据的读取,读取数据后数据格式的转换,还有highchart数据源的配置,伤透了脑筋. anyway,最终开张了.哈哈! 数据库连接:conn_orcale.php <?php $db ...
- 1.3《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——手册页
我们运行的命令行程序,通常在技术上称作shell, 它包含了一个非常强大(也很神秘)的工具,我们将用它来学习更多可用的命令.这个工具本身就是个称作'man'的命令('manual'的简写).它的参数是 ...
- 20155306 白皎 0day漏洞——漏洞利用原理之栈溢出利用
20155306 白皎 0day漏洞--漏洞利用原理之栈溢出利用 一.系统栈的工作原理 1.1内存的用途 根据不同的操作系统,一个进程可能被分配到不同的内存区域去执行.但是不管什么样的操作系统.什么样 ...
- 【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法
如果全部都要重定向的话每一条命令后面>>并不方便,可以这么做.在开头就声明 exec 1>>$log_file表示将脚本中所有的正确输出全部追加到$log_file,错误信息会 ...
- 【php增删改查实例】第六节 - 部门管理模块(开始)
sql建表语句详见:https://www.jianshu.com/p/c88077ed9073 1.新建html模板 新建一个空白的txt文档,然后把后缀名改为.html 用任意一个编辑器打开,比如 ...
- 腾讯云CVM服务器怎么建网站
腾讯云云服务器CVM站在用户的角度看就相当于一台计算机,虽然实际上它是一个虚拟服务器,是一个大的云端服务器集群虚拟出来的一个虚拟服务器,在使用上直接当做一个实际的服务器即可.那么,对于一个新手菜鸟来说 ...
- Gitlab+Jenkins学习目录
Gitlab+Jenkins基础篇 Gitlab+Jenkins学习之路(一)之Git基础 Gitlab+Jenkins学习之路(二)之gitlab部署 Gitlab+Jenkins学习之路(三)之g ...
- IIS充当反向代理转发请求到Kestrel
接着上篇博文为ASP.NetCore程序启用SSL的code,这篇将介绍如何用IIS充当反向代理的角色转发请求到Kestrel服务器 介绍 与ASP.NET不同,ASP.netCore使用的是自托管w ...
- 关于使用单片机读取外部电压ADC阻抗匹配的问题
单片机的基准电压一般为3.3V,如果外部信号超过了AD测量范围,可以采用电阻分压的方法,但是要注意阻抗匹配问题.比如,SMT32的模数输入阻抗约为10K,如果外接的分压电阻无法远小于该阻值,则会因为信 ...