參考《算法設計與分析》一書講解。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))|機率的不超過,故
算法的時間複雜性的指望值不超過。