字符串匹配的随机算法

参考《算法设计与分析》一书讲解。ref:http://blog.csdn.net/zshrong/article/details/5380971算法

对于其失败的几率之小的论证,书中有详细的说明。.net

 

给定两个字符串:X=x1,…,xn,Y=y1,…,ym,看Y是否为X的子串?(即Y是否为X中的一段。)(此问题还可用Rabin-Karp算法、Boyer-Moore算法等)设计

1、随机算法Monte Carlo(用brute-force 思想)blog

记X(j)=xjxj+1…xj+m-1(从X的第j位开始、长度与Y同样的子串),从起始位置j=1开始到j=n-m+1,咱们不去逐一比较X(j)与Y,而仅逐一比较X(j)的指纹Ip(X(j))与Y的指纹Ip(Y)。字符串

因为Ip(X(j+1))能够很方便地根据Ip(X(j))计算出来,故算法能够很快完成。get

不失通常性,设xi(1≤i≤n) 和yj(1≤j≤m)∈{0,1},即X, Y都是0-1串。zsh

Ip(X(j+1)) = (xj+1…xj+m)(mod p)class

=(2(xj+1…xj+m-1)+xj+m)(mod p)循环

=(2(xj+1…xj+m-1)+2mxj-2mxj+xj+m)(mod p)二进制

=(2(xjxj+1…xj+m-1)-2mxj+xj+m)(mod p)

(∵(xy+z)(mod p)=(x(y mod p)+z)(mod p))

          =(2 ( (xjxj+1…xj+m-1)mod p )-2mxj+xj+m)(mod p)

          =(2*Ip(X(j))-xj+xj+m)(mod p)  (﹡)

∴Ip(X(j+1))能够利用Ip(X(j))及(﹡)式计算出来。

算法

一、 随机取一个小于M的素数p,置j←1;

二、 计算Ip(Y)、Ip(X(1))及Wp(=2m mod p);

三、 While j≤n-m+1 do

      {if Ip(X(j))=Ip(Y) then return j /﹡X(j)极有可能等于Y﹡/

       else{使用(﹡)式计算出Ip(X(j+1));j增1}

      }

四、 return 0;      /﹡X确定没有子串等于Y﹡/

时间复杂度:

   Y、X(1)、2m均只有m位(二进制数),故计算Ip(Y)、Ip(X(1))及2m mod p的时间不超过O(m)次运算。

    Ip(X(j+1))的计算:因为2*Ip(X(j))只须要在Ip(X(j))后加个0;当xj为1时,第二部分Wp*xj就是Wp,当xj为0时该部分为0;xj+m或为0或为1,而后进行加减法(O(1)时间)就可获得2*Ip(X(j))-xj+xj+m。但此式还要对p取模。

     因为0≤2*Ip(X(j))≤2p-2,0≤xj≤p-1,0≤xj+m≤1,所以2*Ip(X(j))-xj+xj+m的值在[-(p-1), 2p-1]之间。故实际计算时,若上式是负值,则加上p后即得Ip(X(j+1));

  若为非负,则看其是否小于p,小于p则已得Ip(X(j+1));

  若大于等于p,则减去p后即得Ip(X(j+1))。

    故Ip(X(j+1))的计算只需用O(1)时间。

  因为循环最多执行n-m+1次,故这部分的时间复杂度为O(n)。因而,总的时间复杂性为O(m+n)。

   失败的几率:当Y≠X(j),但Ip(Y)=Ip(X(j))时产生失败。Ip(Y)=Ip(X(j)) 当且仅当p能整除|Y-X(j)|。当p能整除|Y-X(j)|时,p固然也能整除|Y-X(1)| |Y-X(2)|…|Y-X(j)|…|Y-X(n-m+1)|(∵p素数,反之也成立),因为|Y-X(j)|不超过m个二进制位,

       ∴|Y-X(j)|<2m。

     ∴|Y-X(1)| |Y-X(2)|…|Y-X(n-m+1)| < (2m)n-m+1≤2mn。

由数论定理2(若是a<2n,则可以整除a的素数个数不超过p(n)个),能整除|Y-X(1)| |Y-X(2)|…|Y-X(n-m+1)|的素数个数不超过p(mn)个。

因而Pr[failure]=(Y不含在X中、但p(p<M)可以整除|Y-X(1)| |Y-X(2)|…|Y-X(j)|…|Y-X(n-m+1)|的素数的个数)/小于M的素数的个数

≤p(mn)/ p(M) = p(mn)/ p(2mn2)   (取M=2mn2)

≈(mn/loge(mn))/(2mn2/loge(2mn2))= loge(2mn2)/2n loge(mn)

(m≥2时有)≤loge((mn)2)/2n loge(mn)=1/n

即失败的几率只与X的长度有关,与Y的长度无关。

当m=n时,问题退化为断定两个字符串是否相等的问题。

 

2、Las Vegas算法:

当 Ip(Y)=Ip(X(j))时,不直接return j,而去比较Y和X(j), 即在return j以前加一个判断看Y和X(j)是否相等,相等则 return j ,不然继续执行循环。这样,若是有子串X(j)与Y相匹配,该算法总能给出正确的位置即算法出错的几率为0)。

    ∵在最坏状况下算法执行O(mn)时间,而p能整除|I(Y)-I(X(j))|几率的不超过,故

算法的时间复杂性的指望值不超过。

相关文章
相关标签/搜索