FFT字符串匹配


本文半原創

參考資料:其實就是照抄的什么參考啊

我們知道KMP可以用來在線性復雜度內進行制胡竄匹配

今天教您一種新方法:用FFT進行字符串匹配

您可能覺得這很玄學,FFT不是做多項式卷積的嗎,怎么還可以做制胡竄匹配

您先別着急,請接着聽

我們設兩個字符串--模式串\(a\),長度為\(m\),文本串\(b\),長度為\(n\)。設下標為從0開始

定義函數\(a(i)\)返回a串位置i的字符,\(b(i)\)返回b串位置i的字符(其實就是下標)

定義匹配函數\(c(x,y)=a(x)-b(y)\),代表a串x位置和b串y位置是否匹配(也就是是否相同)

如果匹配,那么\(c(x,y)=0\)對吧

然后我們再定義完全匹配函數\(\displaystyle P(x)=\sum_{i=0}^{m-1}c(i,x-m+i+1)\),若\(P(x)=0\),則稱B以第\(x\)位結束的連續\(m\)位與A完全匹配

但是這個匹配函數是有問題的

他會導致字符串"ab"和字符串"ba"匹配,你想想是不是,一個-1一個1,加起來就是0嘍

所以我們稍微改一下匹配函數:\(c(x,y)=(a(x)-b(y))^2\),保證\(c(x,y)\ge 0\),這樣是不是就沒問題了啊

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}(a(i)-b(x-m+i+1))^2\)

您還沒有看出什么玄機來

我們可以把\(a\)串翻轉,設翻轉后的串為\(s\),則滿足\(a(i)=s(m-i-1)\)對吧,下標是從0開始的

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}(s(m-i-1)-b(x-m+i+1))^2\)

繼續觀察!發現什么了???要不我們換一下元,用\(i\)替換\(m-i+1\),注意其中\(i\)的范圍由\([0,m-1]\)變換到了\([0,m-1]\)你直接說沒有變不就得了

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}(s(i)-b(x-i))^2\)

要不我們把完全平方展開下

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}(s^2(i)-2s(i)b(x-i)+b^2(x-i))\)

拆一下sigma

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}s^2(i)+\sum_{i=0}^{m-1}b^2(x-i)-2\sum_{i=0}^{m-1}s(i)b(x-i)\)

這式子是不是不錯啊

第一項是個定值,可以直接算出啦

第二項,由於加的是一段區間,可以O(n)預處理前綴和

第三項!!!這是什么?不就是我們的卷積嗎

FFT即可

時間復雜度O(nlogn)

誒對了

到了這里您可能會發現這個時間復雜度都沒KMP優秀

您可能會問我這個算法有個吊毛用啊,FFT還沒KMP好寫(FFT其實也挺好寫的)

別急聽我接着講

如果我們的字符串里有通配符呢

就是說這個通配符跟什么字符匹配都行(注意是字符而不是字符串)

您會發現KMP就GG了

然后我們繼續考慮FFT做法

這次我們強制令通配符的ascii為0

定義我們的匹配函數\(c(x,y)=(a(x)-b(y))^2a(x)b(y)\),那么是不是對於有通配符的都能保證\(c=0\)了呢

然后就是推一波式子的事情了

大家可以試着推推

行了下面是結果

所以我們的\(\displaystyle P(x)=\sum_{i=0}^{m-1}(s^3(i)b(x-i)-2s^2(i)b^2(x-i)+s(i)b^3(x-i))\)

我們對\(s,s^2,s^3,b,b^2,b^3\)進行FFT,然后再DFT回來就行啦

例題

有了這個算法之后不就是板子題啦

例題

這題可以用SAM做,@顧z

好像還可以用哈希做。。。還是@顧z

溫馨提示:根據生物學知識,人類DNA上的鹼基只有四種

大家可以想一想正解

我們對ATCG貢獻分開算,這里的貢獻指的是不匹配的字符數

假設我們當前強行只計算模式串中A對於匹配串的貢獻

先把模式串翻轉一下

那么我們把模式串的A當做1,T C G都當做0,把文本串的A當做0,T C G都當做1

然后直接讓模式串和文本串卷積(數字很小,可以用NTT優化卷積)

累加的貢獻就是A與TCG不匹配的

最后把所有<=3的位置統計即為答案

總結:

這種帶通配符/不匹配的字符串題我們一般是構造關於字符串的函數,對某個字符串翻轉,然后進行卷積再各種處理。

這種題只是FFT的一種應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM