标签:
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;/** 搜索失败 */ }
标签:
原文地址:http://blog.csdn.net/area_52/article/details/43574111