假如要判断字符串A“AABA”是否是字符串B“AABAACAADAABAABA”的子串

最朴素的算法是枚举B的所有长度为4的子串,然后逐个与A进行对比,这样的时间复杂度是O(mn),m为A的长度,n为B的长度。

另一个做法是用哈希函数计算出A的哈希值,然后计算出B所有长度为4的子串的哈希值,这样比较就可以判断出A是否在B中。虽然这样做的时间复杂度还是O(mn),但是为接下来的滚动哈希打下了基础。

Rabin-Karp算法采用了一种叫做滚动哈希的技巧,对哈希函数的类型有要求。

Rabin-Karp算法的思想:

  1. 假设待匹配字符串的长度为M,目标字符串的长度为N(N>M);
  2. 首先计算待匹配字符串的hash值,计算目标字符串前M个字符的hash值;
  3. 比较前面计算的两个hash值,比较次数N-M+1:
    • 若hash值不相等,则继续计算目标字符串的下一个长度为M的字符子串的hash值
    • 若hash值相同,则需要使用朴素算法再次判断是否为相同的字串;

哈希函数定义如下。

其中Cm表示字符串中第m项所代表的特地数字,有很多种定义方法,我习惯于用java自带的char值,也就是ASCII码值。java中的char是16位的,用的Unicode编码,8位的ASCII码包含在Unicode中。

b是哈希函数的基数,相当于把字符串看作是b进制数。

h是防止哈希值溢出。

滚动哈希的技巧就是:如果已经算出从k到k+m的子串的哈希值H(S[k,k+1...k+m]),那么从k+1到k+m+1的子串的哈希值就可以基于前一个的哈希值计算得出

在不考虑哈希碰撞的前提下,Rabin-Karp算法的时间复杂度就是O(m+n)。

那么来看看POJ 1200

题目大意是有一个字符串,其中有NC种不同的字符,求出其长度为N的不同子串的个数。

这个题目的本意是要利用这个NC,但是我这里只是为了训练滚动哈希,就没有用NC。可以把哈希函数的基数b设为NC,就相当于把字符串转换成了NC进制

 import java.util.HashSet;
import java.util.Scanner; public class test { static long pat; //原始长度为n的子串的哈希值
static long next; //右移一位子串的哈希值
static long B = 100000007; //哈希函数基数
static long max = Integer.MAX_VALUE; //取模防止哈希值溢出 public static void main(String[] args) { HashSet<Long> res = new HashSet<Long>(); //把子串的哈希值放入hashset中,hashset的size就是所求子串个数
Scanner scanner = new Scanner(System.in); int n = scanner.nextInt();
int nc = scanner.nextInt();
scanner.nextLine();
String buff = scanner.nextLine();
char[] s = buff.toCharArray(); long t = 1; //计算出B的n次方
for (int i = 0; i < n; i++) {
t = (t * B) % max;
} //计算出第一个子串的哈希值
for (int i = 0; i < n; i++) {
pat = (pat * B + s[i]) % max;
}
next = pat;
res.add(next); //没有考虑哈希冲突,直接右移计算
for (int i = 0; i + n < s.length; i++) {
next = (next * B + s[i + n] - s[i] * t) % max;
res.add(next);
} System.out.println(res.size());
}
}

poj1200 字符串hash 滚动哈希初探的更多相关文章

  1. Redis支持的数据类型及相应操作命令:String(字符串),Hash(哈希),List(列表),Set(集合)及zset(sorted set:有序集合)

    help 命令,3种形式: help 命令 形式 help @<group> 比如:help @generic.help @string.help @hash.help @list.hel ...

  2. 字符串HASH 学习总结 &amp;&amp; 模板

    一.字符串HASH模板  取自挑战程序设计竞赛(第2版) </pre><pre code_snippet_id="446698" snippet_file_nam ...

  3. Swift3.0语言教程获取字符串编码与哈希地址

    Swift3.0语言教程获取字符串编码与哈希地址 Swift3.0语言教程获取字符串编码与哈希地址,以下将讲解字符串中其它内容的获取方法. 1.获取字符串编码 在NSString中可以使用2个属性获取 ...

  4. 各种字符串Hash函数比较(转)

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  5. [转]各种字符串Hash函数比较

    转自:https://www.byvoid.com/zht/blog/string-hash-compare 常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些 ...

  6. 【转】各种字符串Hash函数比较

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  7. POJ 3865 - Database 字符串hash

    [题意] 给一个字符串组成的矩阵,规模为n*m(n<=10000,m<=10),如果某两列中存在两行完全相同,则输出NO和两行行号和两列列号,否则输出YES [题解] 因为m很小,所以对每 ...

  8. [T]各种字符串Hash函数比较

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

  9. 各种字符串Hash函数比较

    常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法.这些函数使用位运算使得每一个字符都对最后的函数值产生影响.另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎 ...

随机推荐

  1. vue2 自定义全局组件(Loading加载效果)

    vue2 自定义全局组件(Loading加载效果) github地址: https://github.com/ccyinghua/custom-global-component 一.构建项目 vue ...

  2. Spring-Day02-依赖注入-作业

    配置beans约束自动提示 spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html中打开xsd-configuratio ...

  3. MySql Connector/C++8简介

    MySql Connector/C++8是一个用于连接MySQL服务器的C++应用程序.Connector/C++8可用于访问实现文档存储的 MySQL服务器,或者使用SQL查询以传统方式访问.它支持 ...

  4. python实践项目—Collatz序列

    Collatz序列题意说明 编写一个名为collatz()的函数,它有一个名为number 的参数.如果参数是偶数,那么collatz()就打印出number // 2,并返回该值.如果number ...

  5. python中的字符串(str)操作

    字符串是python中数据类型.一般就单引号(‘’)或双引号(“”)引起来的内容就是字符串. 例如:下面两个都是定义字符串 str1 = "hello world" str2 = ...

  6. django之单表查询

    一.创建表 1.创建模型: 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models ...

  7. python基础,导入模块,if语句,while语句

    python基础 python代码 变为字节码 变为机器码 最后执行执行‘文件名.py’文件时出现的‘文件名.pyc’文件为字节码 缓存机制 使用pycharm的时候在文件最开始添加下面这两行代码,中 ...

  8. 贪心算法之Prim

    Prim与Dijistra算法有异曲同工之妙,只不过Dijistra是求最短路径,每次添加到集合中的是到固定起始点的最短距离,而Prim是求最小生成树,是整个图所有权重的最小和,每次添加到集合中的是到 ...

  9. poj3308 Paratroopers

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  10. [Cracking the Coding Interview] 4.2 Minimal Tree 最小树

    Given a sorted(increasing order) array with unique integer elements, write an algorithm to create a ...