字符串匹配算法SMA 总结之二:KR ,Karp Rabin 算法

Karp Rabin 算法是利用hash函数的特性进行字符串匹配的。

KR算法对模式串和循环中每一次要匹配的子串按一定的hash函数求值,如果hash值相同,才进一步比较这两个串是否真正相等

也许你会有这样的疑问,在Brute force暴力匹配中,每一次都把模式串和文本当前字串匹配,现在每一次都计算hash,还要进一步比较,会不会更慢呢?

答案肯定是不会啦,而且事实上KR算法效率很高

第一:不同子串hash值相同是小概率事件

第二:hash函数设计合理的情况下,计算速度相当快

第三:虽然理论上KR算法的时间复杂度是O(m*n),但现实应用中一般是O(m+n)

 

本文使用的hash函数如下:

hash(str[0..m-1])=(str[0]*2^(m-1)+str[1]*2^(m-2)+……+str[m-1]*2^0)mod q

q是一个较大的数,而且最好是素数,而且是大于m的素数。

计算时,*2的运算就使用移位代替了

 

在下面的实现代码中,q取整形最大值,也就是说,可以不用进行模运算了,这种偷工减料的做法只能在模式串很短的情形下才可以用,要不然会溢出的。粗略算了一下,如果模式串是ascii 英文字符,那么模式串长度不超过25的情况下,在32 位机上是没问题的

 

举例说一下KR算法吧:

在我写的这个总结中,各个算法使用的例子都一样,随便找的;

模式串 pattern="pappar"

文本串 text="pappappapparrassanuaragh";

pattern 长度记 pattern_len

预备阶段就是计算pattern的hash,长度为6,那么hash_pattern='p'*2^5+'a'*2^4+'p'*2^3+'p'*2^2+'a'*2^1+'r'*2^0

当然,这里使用的是字符的ascii值

也计算text前六个字符的hash,我们记第一个为hash_text[0]

然后就开始向前移动了,在移动时,要重新计算当前与模式串对应的串的hash值,这个工作叫rehash

初始化 i=0

如果 hash_pattern与hash_text[i]相等,返回 i

如果不等 计算新的hash值,就是text[i..i+patten_len]的hash,

当然这里不会像第一次那样全部计算,方法是

上一次计算的值减去上一次匹配时串的第一个字符乘以 2^pattern_len ,然后乘以2,再加上新加入比较的字符值

根据公式可以很清晰看出来。

就是减去计算中的第一项,把剩下的乘以2,然后在末尾加入新增的字符值

 

看代码吧,很简答的

 

              

hash函数的好坏会直接影响算法的效率,一般应遵循这样的规则:

1  要容易计算,本文中用的就不错,移位的速度大家是知道的

    而且在rehash,就是重新计算hash值时,hash的构造要能避免重新计算整个串的hash,而应该像本例中用到的那样,可以动态地很容易地更新

2 字符串hash值要尽量分布均匀,减少冲突,这是hash函数在任何场合的要求。做到这一点,就能减少匹配中字符的一个个比较,提高性能。如果能够保证每个串的hash值不同,就不用再比较字符了,可以省掉代码中的memcmp运算

   Monte Carlo改进的 RK算法就是只比较hash值,虽然那个改进的算法不能保证正确的结果,但以低于2.53/pattern_len的错误率,而很实用

 

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
字符串匹配算法的一般步骤如下: 1. 选择合适的字符串匹配算法:常见的字符串匹配算法包括暴力匹配算法、KMP算法、Boyer-Moore算法、Rabin-Karp算法等。根据实际情况选择最适合的算法。 2. 预处理模式串(待匹配的字符串):对于某些算法,如KMP算法和Boyer-Moore算法,需要进行预处理以加快匹配过程。这些算法通常会构建辅助数据结构,如最长前缀表、坏字符表等。 3. 执行匹配过程:根据选定的算法,将模式串与目标串进行匹配。 a. 对于暴力匹配算法,从目标串的每个可能位置开始,逐个字符与模式串进行比较,直到找到匹配或者遍历完目标串。 b. 对于KMP算法,利用预处理得到的最长前缀表,在匹配过程中根据不匹配字符的位置和最长前缀表中保存的信息,跳过一些无需比较的字符。 c. 对于Boyer-Moore算法,利用预处理得到的坏字符表和好后缀表,在匹配过程中根据不匹配字符的位置和这些表中保存的信息,跳过一些无需比较的字符。 d. 对于Rabin-Karp算法,通过哈希函数将模式串和目标串的子串进行哈希值比较,若哈希值相等,则再逐个字符比较确认是否匹配。 4. 返回匹配结果:根据匹配过程中的结果,返回匹配成功的位置或者未找到匹配的信息。 需要注意的是,不同算法的步骤和实现细节可能有所不同,具体选择和使用哪种算法取决于实际情况和需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值