kmp算法是用來對字符串進行匹配的一種算法。對於長度爲n的字符串N,要查找其中長度爲m的一個字符串M,傳統的暴力方法的複雜度爲O( n*m ),而用kmp算法時間複雜度爲O( m+n )。因此,kmp算法是一種很實用的算法,在acm競賽中是一種必會算法之一
KMP算法詳解
kmp算法的實現是藉助了一個next數組,該數組是通過對要查找的字符串M進行預處理,然後實現在查找是如果在i位出現不匹配的話,並非從頭到尾全部重新匹配(暴力的方法),而是用next數組找到能夠最大滿足前綴匹配的下標。
具體如圖所示:(圖片參考)
- 構造next數組
- 進行匹配,出現不成功
- 藉助next數組進行保留最長前綴的匹配 v
代碼實現
#include<bits/stdc++.h>
bool SUBMIT = false;
using namespace std;
const int inf = 1000;
int nex[inf];
string s,h;
void Getnex(string m)//對kmp數組的構造
{
nex[0]=-1;
int k=-1,j=0;
while(j<m.size())
{
if(k==-1||m[k]==m[j])
{
k++;j++;
nex[j]=k;
}else
k=nex[k];
}
}
int kmp()//用kmp進行匹配
{
int k=0,j=0;
while(j<h.size())
{
if(k==-1||s[k]==h[j])
{
k++;j++;
}else{
k=nex[k];
cout<<k<<" "<<j<<endl;
}
if(k == s.size())
return j-k;
}
return -1;
}
int main()
{
if(SUBMIT)freopen("i.txt","r",stdin);else _;
cin>>h>>s;
cout<<h<<endl<<s<<endl;
Getnex(s);
for(int i=0;i<s.size();i++)
cout<<nex[i];
cout<<endl;
int ans=kmp();
cout<<ans<<endl;
return 0;
}
- 其實我對kmp構造的快速理解就是kmp首先對字符串處理的保證c = next [ i ]本身指定的位置爲 c 的前 c - 1 位是匹配的。因此,在構造的時候用瞭如果第k 爲 和第 j 爲相等,那麼保證nex [ j + 1 ] = k+1;