鏈接地址:串的模式匹配算法 – BF算法詳解
一、BF算法原理
BF算法是一種蠻力算法,其實現過程沒有任何技巧,就是簡單粗暴地拿一個串同另一個串中的字符一一比對,得到最終結果。
算法目的:確定主串中所含子串第一次出現的位置,這里的子串也稱為模式串。
設計思想:
(1)主串和模式串逐個字符進行比較
(2)當出現字符不匹配(失配)時,主串的比較位置重置為起始位置的下一個字符位置,模式串的比較位置重置為起始字符
回溯關系的確定:i = i - j + 1; //主串指針回溯到比較起始位置的下一個字符位置
關鍵字:循環比較第一次回溯
因為i=j=0都是從0開始,因此逐一比較時下標相等。回溯下標需要使i=1
第二輪回溯經過第一次回溯,i的下標比j的下標大1,因此進行i=i-j+1=2,i指針又往前挪移一位因此i-j是保留之前累積的i>j的差值,然后+1,利用循環便可以繼續累加,達到指針不斷向前移,回溯到比較起始位置的下一個字符位置的效果。
(3)匹配成功返回主串中匹配串的起始位置,否則返回錯誤代碼
簡單理解返回位置,此時i=5為結束匹配時主串指針所指下標,j=3,為子串最后位置元素下標即子串長度,+1便表示位置而不是下標。
二、時間復雜度
設主串長度為m,子串長度為n
該算法最理想的時間復雜度 O(n),n 表示子串的長度,即第一次匹配就成功。BF 算法最壞情況的時間復雜度為 O(n×m),即兩個串每次匹配,都必須匹配至子串的最末尾才能判斷匹配失敗,因此運行了 n×m 次字。
在對數據量大的串進行模式匹配時,算法的效率很低。因此BF 算法還可以改進,就是 KMP 算法,下次再寫文章解釋。
三、C++實現代碼
int BF(const char* S, const char* T)
{
int i = 0, // i主串的起始下標
j = 0; // j子串的起始下標
while (i < strlen(S) && j < strlen(T))
{
if (S[i] == T[j])
{
i++;
j++;
}
else
{
i = i - j + 1; //主串指針回溯到比較起始位置的下一個字符位置
j = 0; //子串回到起始字符
}
}
//j=strlen(T),說明子串遍歷完成,在主串中成功匹配
if (j == strlen(T))
{
return i - strlen(T) + 1;
}
//跳過if運行到此,為i==strlen(B)的情況,說明已經遍歷完主串,匹配失敗
return -1;
}
int main()
{
int number = BF("aaaaabcaaaacac", "aaaac");
cout << number;
return 0;
}
如有不足之處,還望指正 [1]。
如果對您有幫助可以點個贊或關注,將會是我最大的動力 ↩︎