参考《算法设计与分析》一书讲解。ref:http://blog.csdn.net/zshrong/article/details/5380971
对于其失败的概率之小的论证,书中有详细的说明。
给定两个字符串:X=x1,…,xn,Y=y1,…,ym,看Y是否为X的子串?(即Y是否为X中的一段。)(此问题还可用Rabin-Karp算法、Boyer-Moore算法等)
一、随机算法Monte Carlo(用brute-force 思想)
记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))计算出来,故算法可以很快完成。
不失一般性,设xi(1≤i≤n) 和yj(1≤j≤m)∈{0,1},即X, Y都是0-1串。
Ip(X(j+1)) = (xj+1…xj+m)(mod p)
=(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))及(﹡)式计算出来。
算法
1、 随机取一个小于M的素数p,置j←1;
2、 计算Ip(Y)、Ip(X(1))及Wp(=2m mod p);
3、 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}
}
4、 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时,问题退化为判定两个字符串是否相等的问题。
二、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))|概率的不超过,故
算法的时间复杂性的期望值不超过。