前言

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. Maven聚合

    <project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2 ...

  2. MySQL分区技术 (一)

    4:MySQL 分区技术(是mysql 5.1以版本号后開始用->是甲骨文mysql技术团队维护人员以插件形式插入到mysql里面的技术) 眼下,针对海量数据的优化主要有2中方法: 1:大表拆成 ...

  3. .Net Core配置文件

    .Net Core下如何管理配置文件 一.前言 根据该issues来看,System.Configuration在.net core中已经不存在了,那么取而代之的是由Microsoft.Extensi ...

  4. hdu5001(概率dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5001 题意:一个人随即从一个点出发,到达邻接点的概率相同,求出走d步都不会到达1~n点的每一点i的概率 ...

  5. hdu4352(数位dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 题意:求区间L到R之间的数A满足A的的数位的最长递增序列的长度为K的数的个数. 分析:数位dp, ...

  6. [WPF]使用Pack URI路径訪问二进制资源

    一.路径格式定义 完整的URI定义为: pack://application,,,[/可选程序集名称;][可选版本;][目录名称/]文件名 缩略后的写法是: [目录名称/]文件名 二.在XAML代码中 ...

  7. SVN更改登录用户(转)

    一) 原地址:http://www.ixna.net/articles/2606 //证书缓存 $ svn list https://host.example.com/repos/project Er ...

  8. SVN的svnlook命令

    svnlook命令集(zhuanzai) 2011-12-08 17:00:30|  分类: System and CVS|字号 订阅     svnlook 名称 svnlook author — ...

  9. Hdu 3410 【单调队列】.cpp

    题意: 给出一个数组,问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>. eg: ...

  10. 自己定义 ViewGroup 支持无限循环翻页之三(响应回调事件)

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处,再次感谢 ################################ ...