[Algorithm] *String Matching and Hashing
Link: Computer Algorithms: Rabin-Karp String Searching
为了避免挨个字符对文本和模式串进行比较,我们可以尝试一次性判断两者是否相等。
因此,我们需要一个好的哈希函数(hash function)。通过哈希函数,我们可以算出模式串的哈希值,然后将它和文本中的子串的哈希值进行比较。
这里有一个问题,我们必须保证该哈希函数能够对一个较长的字符串返回较短的哈希值。然而,我们又不能指望较长的模式串能得到较短的哈希值。
但除此之外,这个新方法在速度上应该能比暴力法有显著提升。这种更快的方法就是Rabin-Karp算法。
Michael O. Rabin和Richard M. Karp在1987年提出一个想法,即可以对模式串进行哈希运算并将其哈希值与文本中子串的哈希值进行比对。
总的来说这一想法非常浅显,唯一的问题在于我们需要找到一个哈希函数 ,它需要能够对不同的字符串返回不同的哈希值。
例如,该哈希函数可能会对每个字符的ASCII码进行算,但同时我们也需要仔细考虑对多语种文本的支持。
如何找hashing value是个问题。
哈希算法可以有很多种不同的形式,它可能包含ASCII码字符以便对数字进行转化,但也可能是别的形式。我们唯一需要的就是:将一个字符串(模式串)转化成为能够快速进行比较的哈希值。
- 以"hello world"为例,
- 设hash('hello world')=12345。hash('he')=1 表示模式串"he"包含在文本"hello world"中。
由此,我们可以每次从文本中取出长度为m(m为模式串的长度)的子串,然后将该子串进行哈希,并将其哈希值与模式串的哈希值进行比较。

优势 - 多模式匹配
Rabin-Karp算法非常适用于多模式匹配(multiple pattern match)。事实上,它天生就是能够支持此类的操作,这也是它相对于其他字符串查找算法的优势。
算法复杂度
Rabin-Karp算法的复杂度是O(nm),其中n和m分别是文本和模式串的长度。那么它到底比暴力匹配好在哪儿呢?暴力匹配法的算法复杂度同样是O(nm),这样看起来Rabin-Karp算法在性能上并没有多大提升。
然后在实际使用过程中,Rabin-Karp的复杂度通常被认为是O(n+m)。这就使得它比暴力匹配法要快一些,具体见下图。
Rabin-Karp的复杂度理论上是O(nm),但在实际使用中通常是O(n+m)
需要注意的是Rabin-Karp算法需要O(m)的预处理时间。
事实上,由于哈希函数无法保证对不同的字符串产生不同的哈希值,有哈希冲突的现象存在,所以即使模式串的哈希值和文本子串的哈希值相等,也需要对这两个长度为m的字符串进行额外的比对(当然,如果不相等也就不用比对了,其实大部分的时间省在这上面),这时比对的开销是O(m)。最坏情况下,文本中所有长度为m的子串(一共n-m+1个)都和模式串匹配,所以算法复杂度为O((n-m+1)m)。然而实际情况下,需要进一步比对的子串个数总是有限的(假设为c个),那么算法的期望匹配时间就变成O((n-m+1)+cm)=O(n+m)。
应用
我们已经看到Rabin-Karp算法比暴力匹配法其实也快不了太多,那它的应用场景到底是哪里?
译者注:原文没有给出具体答案。要回答这个问题,需要先了解Rabin-Karp算法被称道和诟病的原因。然后根据自己的具体应用需要来做判断。
Rabin-Karp算法被称道的三个原因
它可以用来检测抄袭,因为它能够处理多模式匹配;
Rabin-Karp算法能够有效地检测抄袭虽然在理论上并不比暴力匹配法更优,但在实际应用中它的复杂度仅为O(n+m);
- 如果能够选择一个好的哈希函数,它的效率将会很高,而且也易于实现。
Rabin-Karp算法被诟病的两个原因
- 有许多字符串匹配算法的复杂度小于O(n+m);
- 有时候它和暴力匹配法一样慢,并且它需要额外空间。
[Algorithm] *String Matching and Hashing的更多相关文章
- Aho - Corasick string matching algorithm
Aho - Corasick string matching algorithm 俗称:多模式匹配算法,它是对 Knuth - Morris - pratt algorithm (单模式匹配算法) 形 ...
- Binary String Matching(kmp+str)
Binary String Matching 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Given two strings A and B, whose alp ...
- String Matching Content Length
hihocoder #1059 :String Matching Content Length 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 We define the ...
- (find) nyoj5-Binary String Matching
5-Binary String Matching 内存限制:64MB 时间限制:3000ms 特判: No通过数:232 提交数:458 难度:3 题目描述: Given two strings A ...
- 【CF954I】Yet Another String Matching Problem(FFT)
[CF954I]Yet Another String Matching Problem(FFT) 题面 给定两个字符串\(S,T\) 求\(S\)所有长度为\(|T|\)的子串与\(T\)的距离 两个 ...
- 【ACM】Binary String Matching
Binary String Matching 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Given two strings A and B, whose alp ...
- nyoj 5 Binary String Matching(string)
Binary String Matching 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Given two strings A and B, whose alp ...
- string matching(拓展KMP)
Problem Description String matching is a common type of problem in computer science. One string matc ...
- Binary String Matching
问题 B: Binary String Matching 时间限制: 3 Sec 内存限制: 128 MB提交: 4 解决: 2[提交][状态][讨论版] 题目描述 Given two strin ...
随机推荐
- php boolean
要明确地将一个值转换成 boolean,用 (bool) 或者 (boolean) 来强制转换 var_dump((); // true 当转换为 boolean 时,以下值被认为是 FALSE: 1 ...
- Oracle层次查询和分析函数在号段选取中的应用
转自:http://www.itpub.net/thread-719692-1-1.html 摘要一组连续的数,去掉中间一些数,如何求出剩下的数的区间(即号段)?知道号段的起止,如何求出该号段内所有的 ...
- Jenkins和maven自动化构建java程序
转自:http://www.cnblogs.com/gao241/archive/2013/04/08/3008380.html,版权归原作者所有. Jenkins是一个非常出色的持续集成服务器,本文 ...
- HDU4655【题意+分析】
哎这题有点意思.. 一开始肿么看都不理解题意,发现好多ACM题都这样,好多英文意思不能完全理解,只得照样例猜啦,猜不出来?? 那就靠神队友解释了,囧. 就是排列,涂色使结果最大化. 反正别人的博客把这 ...
- ASP.NET Web API中把分页信息放Header中返回给前端
谈到ASP.NET Web API的分页,考虑的因素包括: 1.上一页和下一页的uri2.总数和总页数3.当前页和页容量 接着是服务端的数据以怎样的形式返回? 我们通常这样写: { totalC ...
- centos7操作SSH/SSHD服务(查看/启动/重启/自启)
查看状态: systemctl status sshd.service 启动服务: systemctl start sshd.service 重启服务: systemctl restart sshd. ...
- XMR恶意挖矿脚本处理笔记
一.登录 攻击者如何登录系统未能查出,所有日志已被清除.为防万一,把系统中没用的用户都删掉并修改其他用户密码. 二.被攻击后的表象 1.服务器资源被大量占用,资源占用率飙升: 2.服务器所有JS文件被 ...
- B+树索引和哈希索引的区别[转]
导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...
- 基于ubuntu搭建 Discuz 论坛
系统要求:Ubuntu 16.04.1 LTS 64 位操作系统 安装 Apache2 ubuntu 需要安装 Apache2 ,使用 apt-get 安装 Apache2(安装好后,您可以通过访问实 ...
- Spring入门教程:通过MyEclipse开发第一个Spring项目
Animal.java package com.project; public class Animal { private String name; public String getName() ...
