串的模式匹配算法 – 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


  1. 如果對您有幫助可以點贊、收藏、關注,將會是我最大的動力 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章