Rabin-Karp算法和指纹思想

Rabin-Karp算法对于随机字符串匹配问题有良好的实用性。它建立在指纹思想上。

主串长度为n   模式串长度为m

假设

※①我们可以在O(m)时间计算一个P的指纹f(P)

※②如果f(P)不等于f(T[s..s+m-1]) 那么P一定不等于T[s..s+m-1]

※③我们可以在O(1)时间比较指纹

※④我们可以在O(1)的时间从f(T[s..s+m-1])计算f(T[s+1..s+m])

指纹可以看成一个十进制的数字,算法的关键是能否在O(1)的时间从f(T[s..s+m-1])计算f(T[s+1..s+m])

如果指纹很大,可以考虑用hash的方式来把数字控制在一个大素数q之内。

即ft = (ft-T[s]*10^(m-1)mod q)*10+T[s+m])mod q 可以在O(1)内完成

其中10^(m-1)mod q可以在预处理中计算一次

伪代码

Rabin-Karp-Search(T,P)
{
    /** q是一个比m大的素数 */
    /** c是经过处理的10(m-1) mod q */
    int fp=0,ft=0;
    for(int i = 0 ; i < m ; i ++) {
        fp = (10*fp+p[i])%q;
        ft = (10*ft+t[i])%q;
    }
    for(int s = 0 ; s <= n-m ; s ++) {
        if(fp == ft) 此处比较是否真的相同,若相同直接返回;
        ft = ((ft-t[s]*c)*10+t[s+m])%q;
    }
    return -1;/** 搜索失败 */
}
时间: 2024-08-02 07:01:18

Rabin-Karp算法和指纹思想的相关文章

Rabin Karp 算法实战

关键字 Rabin karp 算法, C++, ubuntu 14.04, linux, big integer, gmp 为了计算冗余度, 我写出了如下算法 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

排序算法的基本思想和OC代码实现

算法的基本思想和OC代码实现 一 .冒泡排序   (平均时间复杂度 o(N*N))  基本思想:两个数比较大小,较大的数下沉,较小的数冒起来. 过程:比较相邻的两个数据,如果第二个数小,就交换位置 从后向前两两比较,一直到比较最前两个数据.最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了. 继续重复上述过程,依次将第2,3,….,n-1个最小数排好位置. int arr[5]={23,21,45,23,64}; int temp; for (int i=0; i<4; i++) {

经典算法宝典——动态规划思想(六)(2)

1.01背包问题 有N件物品和一个容量为V的背包,第i件物品的体积是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 解析: 这是最基础的背包问题,特点是每种物品仅有一件,可以选择放或不放.用子问题定义状态,即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.其状态转移方程便是f[i][v] = max{f[i-1][v], f[i-1][v-c[i]]+w[i]},这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的,所以有必要将它详细解

经典算法宝典——贪婪思想(五)(1)

贪婪法(Greedy)又叫登山法,它的根本思想是逐步到达山顶,即逐步获得最优解,是解决最优化问题时的一种简单但适用范围有限的策略."贪婪"可以理解为以逐步的局部最优,达到最终的全局最优. 贪婪算法没有固定的算法框架,算法设计的关键是贪婪策略的选择.一定要注意,选择的贪婪策略要具有无后向性,即某阶段状态一旦确定以后,不受这个状态以后的决策影响.也就是说某状态以后的过程不会影响以前的状态,只与当前状态有关,也称这种特性为无后效性.因此,适应用贪婪策略解决的问题类型较少,对所采用的贪婪策略一

经典算法宝典——分治思想(四)(1)

分治法(Divide and Conquer)的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的几个相似问题,以便各个击破,分而治之. 说明: 分治策略的应用很广,具体表现形式各异,比如:折半查找.合并排序.快速排序.二叉树遍历(先遍历左子树再遍历右子树).二叉排序树的查找等算法. 一.分治算法框架 1.算法设计思想 分治法求解问题的过程是,将整个问题分解成若干个小问题后分而治之.如果分解得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出方

hdu2389二分图之Hopcroft Karp算法

You're giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It's a warm, sunny evening, and a soothing wind sends fresh, salty air from the sea. The evening is progressing just as you had imagined.

数据挖掘十大算法总结--核心思想,算法优缺点,应用领域

本文所涉算法均只概述核心思想,具体实现细节参看本博客"数据挖掘算法学习"分类下其他文章,不定期更新中.转载请注明出处,谢谢. 参考了许多资料加上个人理解,对十大算法进行如下分类: ?分类算法:C4.5,CART,Adaboost,NaiveBayes,KNN,SVM ?聚类算法:KMeans ?统计学习:EM ?关联分析:Apriori ?链接挖掘:PageRank 其中,EM算法虽可以用来聚类,但是由于EM算法进行迭代速度很慢,比kMeans性能差很多,并且KMeans算法 聚类效果

经典算法宝典——迭代思想(二)(1)

迭代法(Iteration)也称"辗转法",是一种不断用变量的旧值递推出新值的解决问题的方法. 说明: 迭代算法一般用于数值计算,比如累加.累乘都是迭代算法策略的基础应用. 利用迭代算法策略求解问题,设计工作主要有3步. (1)确定迭代模型 根据问题描述,分析得出前一个(或几个)值与其下一个值的迭代关系数学模型.当然这样的迭代关系,最终会迭代出求解的目标.确定迭代模型是解决迭代问题的关键. (2)建立迭代关系式 递推数学模型一般是带下标的字母,算法设计中要将其转化为"循环不变

八大排序算法实战:思想与实现

摘要: 所谓排序,就是根据排序码的递增或者递减顺序把数据元素依次排列起来,使一组任意排列的元素变为一组按其排序码线性有序的元素.本文将介绍八种最为经典常用的内部排序算法的基本思想与实现,包括插入排序(直接插入排序,希尔排序).选择排序(直接选择排序,堆排序).交换排序(冒泡排序,快速排序).归并排序.分配排序(基数排序),并给出各种算法的时间复杂度.空间复杂度和稳定性. 版权声明: 本文原创作者:书呆子Rico  作者博客地址:http://blog.csdn.net/justloveyou_/