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 哈希)的更多相关文章

  1. 哈希,哈希表,哈希Map

    数组: 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二分查找时间复杂度小,为O(1):数组的特点是:寻址容易,插入和删除困难: 链表: 链表存储区间离散,占用内存比较宽松,故空间复杂 ...

  2. 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 ...

  3. 【 哈希和哈希表】Three Friends【进制哈希】

    Three Friends 传送门:链接 (UPC)或  链接(大视野) 题目描述 Three friends like to play the following game. The first f ...

  4. [PHP内核探索]PHP中的哈希表

    在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据 ...

  5. [基础技能] 安全技术——哈希算法密码破解之彩虹表(Rainbow Table)学习

    1.基础知识 刚刚学习过数字签名的相关知识,以及数字签名的伪造技术,而伪造数字签名归根结底就是密码破解的一个过程,然而直接破解的速度是非常缓慢的,所以有人想出一种办法,直接建立出一个数据文件,里面事先 ...

  6. 简单的哈希表实现 C语言

    简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ...

  7. Memcached 笔记与总结(8)Memcached 的普通哈希分布算法和一致性哈希分布算法命中率对比

    准备工作: ① 配置文件 config.php ② 封装 Memcached 类 hash.class.php,包含普通哈希算法(取模)和一致性哈希算法 ③ 初始化 Memcached 节点信息 in ...

  8. 哈希(Hash)与加密(Encrypt)的基本原理、区别及工程应用

    0.摘要 今天看到吉日嘎拉的一篇关于管理软件中信息加密和安全的文章,感觉非常有实际意义.文中作者从实践经验出发,讨论了信息管理软件中如何通过哈希和加密进行数据保护.但是从文章评论中也可以看出很多朋友对 ...

  9. Java中的哈希

    Java中的哈希 前言 在开发中经常用到HashMap.HashSet等与哈希有关的数据结构,一直只知道这些哈希的数据结构不保证顺序,不清楚具体什么情况.所以在这里大致总结一下.   Java的Has ...

随机推荐

  1. 20155209林虹宇Exp4 恶意代码分析

    Exp4 恶意代码分析 系统运行监控 使用schtasks指令监控系统运行 新建一个txt文件,然后将txt文件另存为一个bat格式文件 在bat格式文件里输入以下信息 然后使用管理员权限打开cmd, ...

  2. 3、class文件加载过程

    1.加载2.链接(检验/准备/解析) 1/检验过程:检验class的数据格式.2/准备过程:创建静态域,并将这些域设为默认值.3/解析过程:在一个Java类中会包含对其它.类或接口的形式引用,包括它的 ...

  3. 蒙特卡罗方法 python 实现2

    如果不考虑作图,这里的两个例子可以改写成下面的样子: 求圆周率 import random ''' 蒙特卡罗模拟 投点法计算圆周率 ''' # 投点游戏 def play_game(): # 圆 r ...

  4. Android几行代码实现监听微信聊天

    原创作品,转载请注明出处,尊重别人的劳动果实. 2017.2.7更新: *现在适配微信版本更加容易了,只需要替换一个Recourse-ID即可 *可以知道对方发的是小视频还是语音,并获取秒数. *可以 ...

  5. 移动端jq及zepto事件绑定

    最近做移动端网页,用到了zepto.js , 其大致用法跟 jquery 差不多,但是在时间绑定的时候被困了好久的坑. 这里说的主要是给未来元素绑定事件.未来元素:这里指的是通过 ajax 请求得到数 ...

  6. 【OpenCV学习笔记之一】图像加载,修改及保存

    加载图像(用cv::imread)imread功能是加载图像文件成为一个Mat对象 其中第一个参数表示图像文件名称第二个参数 表示加载的图像是什么类型 支持常见的三个参数值IMREAD_UNCHANG ...

  7. 冒泡排序算法的C++,Java和Python实现和冒泡排序算法三种语言效率的比较

    冒泡排序原理: 这一篇百度经验讲得很好,我不多说了 https://jingyan.baidu.com/article/6525d4b13f920bac7d2e9484.html 他讲的是C语言,没有 ...

  8. mac10.12.6系统配置clion编写CMakeLists文件运行opencv3

    按照mac10.12.6系统使用cmake安装opencv3.3.0+opencv_contrib-3.3.0下载编译安装好了文件以后,装好clion编译器,新建C++可执行工程,编写代码 opecv ...

  9. Unity3d Transform.forward和Vector3.forward的区别!

    在Unity中有两个forward,一个是Transform.forward一个是Vector3.forward. 对于Vector3来说,它只是缩写.没有其它任何含义. Vector3.forwar ...

  10. PowerDesigner数据库设计实用技巧

    欢迎大家补充,谢谢! 1. 原始单据与实体之间的关系 可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体.在特殊情况下,它们可能是一对多或多对一的 ...