字串匹配演算法(KMP)

2022-07-29 04:24:10 字數 2246 閱讀 5294

字串匹配運用很廣泛,舉個簡單例子,我們每天登qq時輸入賬號和密碼,大家有沒有想過賬號和密碼是怎樣匹配的呢?登入需要多長時間和匹配演算法的效率有直接的關係。

首先理解一下字首和字尾的概念:

給出乙個問題:現在有乙個文字串s=「

bbc abcdab abcdabcdabde

」和乙個搜尋串(模式串)p="

abcdabd

",要查詢p在s中的位置。我們常用的一種方法就是暴力求解,暴力求解的思想是:讓模式串從文字串的第乙個字元開始往後匹配,假設現在文字串匹配到

i 位置,模式串匹配到 j 位置:

如果當前字元匹配成功,則 i++, j++

如果當前字元匹配不成功,i 要回溯 , j 要歸零 ;

首先,字串"bbc abcdab abcdabcdabde"的第乙個字元與搜尋詞"abcdabd"的第乙個字元,進行比較。因為b與a不匹配,所以搜尋詞後移一位。

因為b與a不匹配,搜尋詞再往後移。

就這樣,直到字串有乙個字元,與搜尋詞的第乙個字元相同為止。

接著比較字串和搜尋詞的下乙個字元,還是相同。

直到字串有乙個字元,與搜尋詞對應的字元不相同為止。

這時,最自然的反應是,將搜尋詞整個後移一位,再從頭逐個比較。這樣做雖然可行,但是效率很差,因為你要把"搜尋位置"移到已經比較過的位置,重比一遍。

相應**如下:

#include #include using namespace std;

int main()

}if(flag == false)

cout << "匹配失敗" << endl ;

return 0;

}

以上**可以進行簡化:

#include #include using namespace std;

int main()

else

}if(j == lenp)

cout << i - j + 1 << endl ;

else

cout << "匹配失敗" << endl ;

return 0;

}

暴力求解有很多比較都是多餘的,下面介紹一種比較快速的查詢方法。

kmp演算法:

knuth-morris-pratt字串查詢演算法,簡稱「kmp」演算法,常用於在乙個文字串中查詢乙個模式串出現的位置。

思想:利用模式串中在匹配過程中,不匹配字元前面那一段最長字首字尾,盡可能減少多餘的匹配。

首先需要對模式串進行處理,這裡需要定義乙個next陣列,某個字元失配時,該字元對應的next 值會告訴你下一步匹配中,模式串應該跳到哪個位置。

**雛形如下,其中next陣列還未知:

#include using namespace std;

int main()

else

}if(j == lenp)

cout << i - j + 1 << endl ;

else

cout << "匹配失敗" << endl ;

return 0;

}

下面求解next陣列:

next陣列中儲存的就是當前模式串已匹配過的字元組成的字串最長字首字尾的長度:

KMP演算法 字串匹配

kmp演算法基本思想 我們在用常規的思想做 字串匹配時候是 如 對如 字元如果 t abab 用p ba 去匹配,常規思路是 看 t 第乙個元素 a 是否 和p 的乙個 b 匹配 匹配的話 檢視各自的第二個元素,不匹配 則將 t 串的 第二個元素開始 和 p 的第乙個匹配,如此 一步一步 的後移 來...

KMP字串匹配演算法

kmp核心思想 計算模式串的next陣列,主串的索引在比較的過程中不回朔 ifndef kmp h define kmp h class kmp endif include kmp.h include include include using namespace std int kmp calcu...

KMP字串匹配演算法

在介紹kmp演算法之前,先介紹一下bf演算法。一.bf演算法 bf演算法是普通的模式匹配演算法,bf演算法的思想就是將目標串s的第乙個字元與模式串p的第乙個字元進行匹配,若相等,則繼續比較s的第二個字元和p的第二個字元 若不相等,則比較s的第二個字元和p的第乙個字元,依次比較下去,直到得出最後的匹配...