一個匹配優化的問題

前幾天bbs上看到這樣一個問題:

現在有一系列的字符串S=S1, S2, ..., Sn,另外還有一系列的正則表達式或者模式P=P1, P2, ..., Pm。

有什麼比較好的算法來讓每一個字串對應到一個模式上去嗎?(如果有多個對應的則要求對應到最前面出現的模式)

現在用的是最顯而易見的算法:遍歷S,把每一個字串Si,嘗試匹配P中的每一個直到成功則記下它Pj。

這樣時間複雜度是n*m,有點慢。。不知道有沒有更好的算法。


我的回答是這樣的:

實際上,這個問題的本質取決於你的需要匹配的字符串的模式的分佈情況。

因爲你的所有的字符串都需要匹配,因此n是需要全部遍歷一遍的。最好的情況是每次都第一個匹配成功。因爲假設這些字符串又是全完獨立的隨機字符串,所以也可能產生每次都是最後一個匹配到的情況。


這只是初步分析。進一步分析是:

一.這些字符串究竟是不是完全隨機的。因爲一般來說,輸入的序列往往會呈現出某種特徵。

典型的特徵有兩種:

1.局部性:就是出現過的字符串模式很快又會出現。

2.互斥性:出現過的字符串模式不會再出現。

應對這個特徵的解決方案是把匹配模式做成一個鏈表,從頭到尾遍歷。如果是局部性的,每次匹配成功後把這個模式放到鏈表頭,如果是互斥性的,就把他放到鏈表尾。

可以證明的是,這種方式不會比運氣最好的情況(準確說是運氣最壞情況下的最好算法)差到哪裏去。也就是所謂的競爭分析。


二.這些匹配特徵內部是不是有某種特別的聯繫。

我所說的條件是否寬鬆是其中一條。

舉個例子,假設一共兩個匹配條件:字符串包含a,字符串包含ab。

顯然包含a要比包含ab寬鬆,也就是被匹配到的概率要更大。並且這其中包含了一個重要的特徵,就是如果第一條不匹配,那麼第二條肯定也是不匹配的。因此下一個匹配比較就可以省略了。把類似的匹配條件放在一個鏈表節點裏。比如把寬鬆的放在這個節點子鏈表的前面,把嚴格的放在鏈表的後面。(實際上嚴格的策略永遠也不會被匹配到)




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