两个字符串模式匹配的算法

      今天看了一下查找子串在某个文本中出现的位置的两个算法。一个是Karp-Rabin算法,另外一个是Knuth-Morris-Pratt算法。

      先来说明一下这个Karp-Rabin算法。该算法提出了一个简单的子串位置查询的方法,区别于brute force方法的O(m*n)的时间复杂度,该算法在最坏情况下的时间复杂度是O(m*n),其平均复杂度为O(m+n)。其中m为子串的长度。n为文本的长度。该算法使用hash函数来检查两个序列。从而查找出子串在文本中出现的位置。其中hash function需要具有以下属性:

       1、能够很快地计算出来;

       2、严格区分出不同的字符串;

       3、在已知hash(y[i ... i+m-1])的情况下可以很容易地求解出hash(y[i+1 ... i+m]),具体的求解式为:

        hash(y[i+1 ... i+m]) = rehash(y[i],y[i+m],hash(y[i...i+m-1]);

      对长度为m的子串w,定义hash(w) = (w[0]*2m-1+w[1]*2m-2+...+w[m-1])mod q

     其中q为一个大的素数。另外,我们定义rehash(a,b,h) = (h-a*2m-1)*2+b)mod q .

      在查找模式串w的过程中,hash(w)需要与hash(y[i..i+m-1])进行比较,其中(0<=i<n-m)。如果发现有hash值相等的,则需要对x=y[i..i+m-1]进行逐个字符的比较,以确定其是否相同。

       如: w= ing.

        则hash(w) = 105*22+110*2+103 = 743  按照字符的ASCII码进行计算的。

         y =  s   t    r     i     n    g             m    a     t     c     h     i      n      g

    hash =       806 797 776 743 678 585 443 746 719 766 709 736 743

    这样,如果在文本串中有和子串相同hash值的字符串,则逐字符地比较这两个hash函数值相同的字符串,如果相同,则在文本中找到子串,如果不同,则文本中没有要找的子串。 该方法相比于brute force算法上面有改进,但其最坏的时间复杂度却和brute force算法相同。

        下面我们引入的Knuth-Morris-Pratt算法,该算法查找子串的时间复杂度是线性的。

         假定x[0...m-1]和文本字符y[i...i+m-1]对齐,假定它们的第一个不匹配的字符是y[i+j]和x[j] (1<j<m)。则可以推出y[i...i+j-1] = x[0...j-1] = u并且a = y[i+j] != x[j] = b。当移动下标重新进行比对的时候,很显然,我们希望x的前缀v和文本的u的部分后缀匹配。此外,如果我们能够避免其他立马可能出现的不匹配字符的话,x串的前缀v后面紧跟的字符肯定不能是b了。

            今天先写到这里了,这两个算法现在只是一个初步的了解,刚开始看这篇文章,关于算法的描述基本上是翻译了以下“Review Pattern Matching and Text Compression Algorithms”这篇文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值