今天學習了乙個新演算法:kmp演算法
其實很久以前學過早忘了
kmp演算法是用於處理字串問題的演算法。
參考matrix67的部落格:kmp演算法詳解|matrix67
假設有字串a和b,要求判斷b是否是a的字串
其實就是對於每個i,求最大的j,使得ai
−j+1
→i與b
1→j 一一匹配
能匹配j指標就往後跳乙個
否則就需要往回退
如下圖:
我們希望往回退得越少越好,
通過上圖可以發現,其實最佳方案就是 最長相同前字尾
對字串b的每個字首字串,找乙個最長的長度l,使得長度為l的前字尾相同
這個可以預處理出來,第i個字首的長度l記為next[i]
那麼每次不匹配就往回退next[j]即可
只要出現j==m的情況就說明b是a的字串
**如下:
for (int i=1,j=0;i<=n;i++)
}
下面來說預處理的事。
怎樣得到next?假設已經得到next[1~i-1],現在求next[i]
設next[i-1]為j,如果b[j+1]==b[i],那麼next[i]=next[i-1]+1
否則需要縮小j的範圍。
有讀者可能會發現,尋找next[i]的過程其實就是將b[1~i-1]與b匹配的過程
所以回退next[j]即可
**如下:
nxt[1]=0;
for (int i=2,j=0;i
<=n;i++)
接下來證明複雜度。
通過上面的**可以發現,j指標最多向後跳n次
而j在任何時候都是大於0的,所以回退也是o(n)級別的
所以kmp演算法的複雜度是o(n)
通過next陣列,可以得到乙個字串的最小週期以及最小迴圈節
最小週期為n-next[n],如果週期能整除n,最小迴圈節就是週期
否則是n
KMP演算法及其優化
今天來記錄一下,關於字元匹配的kmp演算法。給定字串text和pattern,需要判斷字串pattern是否為test的子串。pattern一般稱為模式串,text為文字串。若匹配成功,則讓函式返回,匹配開始處的下標,否則,返回 1。假設有乙個字串s,它以i號位作為結尾的子串就是s 1 i 對該字串...
KMP演算法及應用
kmp演算法用來解決一系列字串單模式匹配問題,其以難理解,難記憶著稱。其next陣列的構造就如同ac自動機中的fail指標,就是如果匹配失敗,字串應從 開始繼續匹配。這裡的next陣列表示 next i 前i個字元的公共最長前字尾長度。覺得對於kmp演算法,這篇寫的不錯 現在來講一下應用。給定兩個字...
經典演算法之KMP演算法及其優化
kmp演算法的具體分析見 author s email wardseptember gmail.com date 2017.12.18 kmp演算法 include include using namespace std define maxsize 50 void getnext char sub...