如何高效地進行遠程大規模字符串比較問題

關鍵字 (keywords):大規模 字符串 匹配 遠程 比較 快速     

 

 

        隨着互聯網的快速發展,信息量成爆炸趨勢,大規模的文本處理已經成爲一個挑戰,今天這裏我想解決一個海量數據中會經常遇到的一個問題,就是如何在兩臺主機之間進行高效地大規模字符串比較問題,如果給定100MB字符串A和1GB字符串B分別在遠程在兩臺主機上,那我想比較A是否是B的字串?


怎麼辦呢?很明顯,我們用一般的算法是無法解決這個問題的。因爲如果是一般的算法,肯定是先傳送這兩個字符串到同一臺機子上,然後再用KMP等算法進行字符串比較,我想大家都知道其實這樣是非常耗時的,我下面給出了我的解法,使用的算法是隨機算法,解決的大致如下:

 

先將A字符串轉爲01串,轉換後,設01串的長度爲lenA,然後計算該字符串的指紋,指紋是一個整數,在這裏的指紋即能唯一表示A的字符串,如同每一個人的都有自己的手指指紋一樣,是唯一的。

同樣將B串轉爲10串,轉換後,假設01串的長度爲lenB,那麼它的指紋個數爲(lenB-lenA+1)

如下圖所示:

從上圖中,可以看到,B串共有n個指紋。

那麼怎麼計算這個指紋呢?

一般計算指紋如下:令I(x)是x的編碼,去Ip(x)=I(x)(mod p)作爲x的指紋。

Ip(x)是x的指紋

I(x)是x的編碼,就是我們說的原來的字符串

p是一個小於M的素數,M可根據具體需要調整,這裏取M=2*n^2

Ip(x)等於I(x)%p

其實就是把所有01串轉爲一個大數然後mod p 後的結果就是指紋

 

我的算法如下:用java實現

 

首次計算時用上面的算法,再計算第二個時候用下面另外一種方法,主要基於第一種方法的結果計算得到

 

我的算法實現如下:

 

另外一個問題是快速求得大素數p,p是小於M,但與M(M=2n^2)相近的素數,這裏我用了Miller-Rabin的一個改進算法

時間複雜度爲O(k*(log(n))^3),n是M的值,k與素數的誤判率有關,誤判率爲1/2^k,如果k取100,基本上就已經不可能出現錯誤了

我將抽取時間寫另外一篇blog是關於大素數高效判斷的方法,也是隨機算法。


至此,問題也就解決了,其他的只需要把主程序寫一下就行了,我的主程序如下:

這裏假設兩個串都在一臺機器上,傳輸被忽略了,如要模擬,其實只須傳輸一個指紋到另一臺主機就行了

 

 

測出結果:與A相同的指紋,準確率(1-1/2^100)

count:1 29747

count:2 50706

count:3 83590

count:4 96803

count:5 103301

count:6 229482

count:7 236235

count:8 246710

count:9 334959

count:10 353036

count:11 363681

count:12 384086

count:13 388068

count:14 417645

count:15 482496

count:16 483673

count:17 487611

count:18 494533

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章