前言

Rabin-Karp字符串匹配算法和前面介绍的《朴素字符串匹配算法》类似,也是相应每一个字符进行比較。不同的是Rabin-Karp採用了把字符进行预处理,也就是对每一个字符进行相应进制数并取模运算,类似于通过某种函数计算其函数值,比較的是每一个字符的函数值。

预处理时间O(m)。匹配时间是O((n-m+1)m)。

Rabin-Karp算法的思想:

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

Rabin-Karp算法实现

伪代码:

  1. Rabin_Karp_search(T, P, d, q)
  2. n = T.length;
  3. m = P.length;
  4. h = d^(m-1)mod q;
  5. p = 0;
  6. t = 0;
  7. for i =1 to m
  8. p = (d*p+P[i]) mod q;
  9. t = (d*t+T[i])mod q;
  10. for i = 0 to n-m
  11. if p==t
  12. if P[1..m]==T[i+1..i+m]
  13. print"Pattern occurs with shift"i
  14. if i<n-m
  15. t = d(t-T[i+1]h) + T[i+m+1]mod q

源代码:

  1. // Rabin Karp Algorithm
  2.  
  3. #include<iostream>
  4. #include<string>
  5.  
  6. using namespace std;
  7.  
  8. void Rabin_Karp_search(const string &T, const string &P, int d, int q)
  9. {
  10. int m = P.length();
  11. int n = T.length();
  12. int i, j;
  13. int p = 0; // hash value for pattern
  14. int t = 0; // hash value for txt
  15. int h = 1;
  16.  
  17. // The value of h would be "pow(d, M-1)%q"
  18. for (i = 0; i < m-1; i++)
  19. h = (h*d)%q;
  20.  
  21. // Calculate the hash value of pattern and first window of text
  22. for (i = 0; i < m; i++)
  23. {
  24. p = (d*p + P[i])%q;
  25. t = (d*t + T[i])%q;
  26. }
  27.  
  28. // Slide the pattern over text one by one
  29. for (i = 0; i <= n - m; i++)
  30. {
  31.  
  32. // Chaeck the hash values of current window of text and pattern
  33. // If the hash values match then only check for characters on by one
  34. if ( p == t )
  35. {
  36. /* Check for characters one by one */
  37. for (j = 0; j < m; j++)
  38. if (T[i+j] != P[j])
  39. break;
  40.  
  41. if (j == m) // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
  42. cout<<"Pattern found at index :"<< i<<endl;
  43. }
  44.  
  45. // Calulate hash value for next window of text: Remove leading digit,
  46. // add trailing digit
  47. if ( i < n-m )
  48. {
  49. t = (d*(t - T[i]*h) + T[i+m])%q;
  50.  
  51. // We might get negative value of t, converting it to positive
  52. if(t < 0)
  53. t = (t + q);
  54. }
  55. }
  56. }
  57.  
  58. int main()
  59. {
  60. string T = "Rabin–Karp string search algorithm: Rabin-Karp";
  61. string P = "Rabin";
  62. int q = 101; // A prime number
  63. int d = 16;
  64. Rabin_Karp_search(T, P,d,q);
  65. system("pause");
  66. return 0;
  67. }

參考资料:

《算法导论》

http://www.geeksforgeeks.org/searching-for-patterns-set-3-rabin-karp-algorithm/

版权声明:本文博主原创文章。博客,未经同意不得转载。

算法——字符串匹配Rabin-Karp算法的更多相关文章

  1. 算法——字符串匹配之BM算法

    前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...

  2. 实现字符串匹配的KMP算法

    KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...

  3. Luogu 3375 【模板】KMP字符串匹配(KMP算法)

    Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...

  4. 字符串匹配的 Boyer-Moore 算法

    上一篇文章,我介绍了 字符串匹配的KMP算法 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的” 查找” 功能(Ctrl+F),大多采用 Boyer-Moore 算法. 下面,我根据 M ...

  5. 字符串匹配的 KMP算法

    一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...

  6. 字符串匹配的kmp算法 及 python实现

    一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...

  7. HDU 1711 Number Sequence (字符串匹配,KMP算法)

    HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...

  8. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  9. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

随机推荐

  1. 利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)

    利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)作者:Tuuzed(土仔)   发表于:2008年3月3日23:12:38 版权声明:可以任意转载,转载时请 ...

  2. Loser tree in Python | Christan Christens

    Loser tree in Python | Christan Christens Loser tree in Python I am taking an Advanced Data Structur ...

  3. Flume传输数据事务分析

    Flume传输数据事务分析 本文基于ThriftSource,MemoryChannel,HdfsSink三个组件,对Flume传输数据的事务进行分析.假设使用的是其它组件.Flume事务详细的处理方 ...

  4. [非官方]ArcGIS10.2 for Desktop扩展工具包——XTools Pro

    XTools Pro 是一套为ArcGIS平台设计的矢量空间分析. 形状转换和表管理扩展工具,大大增强了 ArcGIS 的功能,使用该工具能够提高 ArcGIS 用户的效率和性能. XTools Pr ...

  5. Visual Studio使用正则表达式快速统计总共代码行数

    原文:Visual Studio使用正则表达式快速统计总共代码行数 按CTRL+SHIFT+F,勾上支持正则表达式,然后输入搜索内容: <span style="font-family ...

  6. linux中怎样设置DHCP

    linux怎样设置DHCP 环境:RH linux 9.0 使用linux下经常使用的dhcpd包. 最新版本号 dhcp3.0.5 下载地址: 下载 1.安装: 先拷贝dhcp-3.0.5.tar. ...

  7. PSU 离11.2.0.3.0 -&gt; 11.2.0.3.11 如果解决冲突的整个

    Oracle rdbms 扑灭psu离11.2.0.3.0升级到11.2.0.3.11 参考patch :18522512 停止应用,停止听音乐并DB,将db的oracle_home在下面OPatch ...

  8. STL源代码剖析 容器 stl_hashtable.h

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie hashtable ------------------------------------ ...

  9. BZOJ 1109 POI2007 堆积木Klo LIS

    题目大意:给定一个序列,能够多次将某个位置的数删掉并将后面全部数向左串一位,要求操作后a[i]=i的数最多 首先我们如果最后a[i]=i的数的序列为S 那么S满足随着i递增,a[i]递增(相对位置不变 ...

  10. 利用 C++ 单向链表实现队列

    利用C++ 单向链表实现数据结构队列,其实和上一篇基本内容相同,仅仅是插入的时候在链表的尾部插入,取元素都是一样的,都从头部取. #pragma once #include "stdio.h ...