字符串匹配之Rabin-Karp

本文深入探讨了Rabin-Karp算法,一种高效的字符串匹配算法。通过对比算法导论一书,作者更倾向于网上资源的理解方式。文章详细解释了算法中的关键公式h=dm-1(modq),并指出在ts≡p(modq)时,尽管ts可能不等于p,但ts≠p时几乎可以肯定。为了减少伪命中的出现,当ts≡p(modq)时,会使用朴素的字符串匹配算法进行验证。此外,文章还提供了Rabin-Karp算法的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    再次我推荐touzani的专栏的那篇文章。虽然说和算法导论上面的是一样的,但是我还是没心情看那本黑书,密密麻麻的都是字,还是看网上的爽点。

    下面我摘抄点重点的部分来帮助理解吧。

https://p-blog.youkuaiyun.com/images/p_blog_youkuaiyun.com/touzani/303255/o_image006.jpg

其中的 h = d m -1 (mod q)

但是加入模q后,由tsp (mod q)不能说明 ts = p. 但tsp (mod q), 可以说明 tsp,

因此当 tsp (mod q)时, 再用朴素的字符串匹配算法验证 ts = p . 如果q足够大,可以期望伪命中很少出现。
 
 
算法
RABIN-KARP-MATCHER(T, P, d, q)
 1 n  length[T]
 2 m  length[P]
 3 h  dm-1 mod q
 4 p  0
 5 t0 0
 6 for i  1 to m            Preprocessing.
 7     do p  (dp + P[i]) mod q
 8        t0 (dt0 + T[i]) mod q
 9 for s  0 to n - m        Matching.
10     do if p = ts
11           then if P[1  m] = T [s + 1  s + m]
12                   then print "Pattern occurs with shift" s
13        if s < n - m
14           then ts+1 (d(ts - T[s + 1]h) + T[s + m + 1]) mod q
C++代码:
void Rabin_Karp(char*T,char* W,int d,int q )
{
//搜索W在T中的位置
//参数d:字母表的进制,即字母表的元素个数
//参数q:一个比较大的素数,只需d*q<字长
int n=strlen(T);
int m=strlen(W);
if(n<m) return;
int i;
__int64 h=1;
for(i=1; i<=m-1; i++) //计算h
h=(h*d)%q;
__int64 w=0,t=0;
//预处理,计算P,t0
for(i=0; i<m; i++)
{
w=((d*w+W[i])%q);
t=((d*t+T[i])%q);
}
int s;
for(s=0; s<n-m+1; s++) //匹配
{
if(w==t)
{
for(i=0; i<m; i++) //进一步验证
{
if(W[i]!=T[s+i])
break;
}
if(i==m)
{
nCount++;
}
}
if(s<n-m)
t=(d*(t-T[s]*h)+T[s+m])%q; //计算ts+1
}
}

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值