前言:今天上數據結構的課後想到之前學這個算法的時候並沒有寫一個詳細的博客,現在補一個,也算是加深印象。
串模式匹配算法
子串的定位運算通常稱爲串的模式匹配或串匹配。此算法的應用非常廣泛,比如在 搜索引擎拼寫檢查,語言翻譯,數據壓縮等應用中,都需要進行傳匹配
串的模式匹配設有兩個字符串S和T,設S位主串,也稱正文串;設T爲子串,也稱爲模式在子串中查找與模式T相匹配的子串,如果匹配成功,確定相匹配的子串中的第一個字符串S中出現的位置。
著名的模式匹配算法有BF算法和KMP算法,下面詳細介紹兩種算法。
1.BF算法
BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是將目標串S的第一個字符與模式串T的第一個字符進行匹配,若相等,則繼續比較S的第二個字符和 T的第二個字符;若不相等,則比較S的第二個字符和T的第一個字符,依次比較下去,直到得出最後的匹配結果。
比如
int BF(char S[],char T[],int pos)
{//c從第pos位開始搜索匹配
int i=pos,j=0;
while(S[i+j]!='\0'&&T[j]!='\0')
{
if(S[i+j]==T[j])
j++;
else
{
i++;
j=0;
}
}
if(T[j]=='\0')//返回的是匹配找到的開始位置
return i+1;
else
return -1;
}
BF算法比較直接,是一種蠻力算法,該算法最壞情況下要進行M*(N-M+1)次比較,時間複雜度爲O(M*N)。
這個算法的話時間複雜度高。
那麼對於有需要效率非常高的時候。我們就需要使用效率非常高的字符串匹配算法,即KMP算法。
KMP算法
這個改進算法是由Knuth ,Morris和 Pratt 同時設計實現的,因此簡稱爲KMP。
這個算法是在BF算法上改進的,那麼我們先來了解一下它是怎麼改進的。
每當一趟匹配過程中出現字符比較不相等時,不需要回溯i指針,而是利用已經得到的"部分匹配"的結果將模式向右"滑動"儘可能遠的一段距離後,繼續進行比較。
舉個例子:
第一躺 : ababcabcacbab
: abc
第二趟:ababcabcacbab
: abc
第三趟 :ababcabcacbab
: abc
或者看動態圖
通過這個圖行我們可以理解了改進 後是怎麼比較的,那麼知道原理後,我們需要去實現KMP算法。下面就是開始實現:
我們先得到next[],然後實現KMP算法。
void get_next(string t,int next[])//
{
int len=t.length();
i=1;
nex[1]=0;
j=0;
while(i<len)
{
if(j==0||t[i]==t[j])
{
++i,++j;
next[i]=j;
}
else
j=next[j];
}
}
int KMP(string s,string t,int pos)
{
i=pos,j=1;
while(i<=s[0]&&j<=t[0])
{
if(j==0||s[i]==s[j])
{
++i;++j;
}
else
j=next[j];
}
if(j>t[0])
{
return i-t[0];
}
else
return 0;
}