update(20200316):重寫介紹(五年前好像什麼都沒寫一樣)。
1、前言
好吧我得承認這東西應該是早就要會了的。。。雖然感覺上用的不多,但是當我開始接觸ac自動機的時候,發現這是乙個很必要的知識點,所以今天來講一講。
然而有乙個問題了——為什麼我一直沒有搞懂就是因為許多許多次我看網上的一些文章就發現總是弄得很複雜,所以我推薦大家直接看**,更容易弄懂。反正我就這麼明白了。在ac自動機明白之後,將會有更詳細地闡述。
2、介紹
kmp演算法,是在普通字串匹配演算法的基礎上改進的演算法,核心在於:利用每次匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。首先我們先看看普通匹配演算法的思路:假設讀入a, b兩個字串,a為主串,b為模式串。從a的第一位起,與b的第一位起逐位匹配,直到匹配到模式串串尾。如果出現不匹配情況,則退出該次匹配,從a的第二位起,與b的第一位起逐位匹配,以此類推,即最壞匹配複雜度為o(a.len * b.len)。
kmp演算法引入乙個新的陣列:fail陣列,表示b的第i位起的子串與b本身串的最長字首長度。例如:
同樣地,你也可以理解為表示b的前i位子串的公共前字尾長度(即字首和字尾相同)。
預處理出fail陣列的意義是什麼?前面提到了,每次匹配失敗,我們都需要從主串第一位重新來過。
再來看乙個例子,如圖所示,在匹配過程中匹配到第6位時,我們發現匹配失敗了;而已匹配上的前5位,其第5位的fail值為3,表示前5位的公共前字尾長度為3,也就是說,[3, 5]子串和[1, 3]子串是一致的,那我們也就不再需要對這一段進行一一匹配了,從而直接從a的第5+1=6位和b的第3+1=4位開始匹配。
以此類推,可以理解為b串自身整體右移,使其與a串匹配,故時間複雜度約為o(a.len + b.len),大幅降低。
3、**
1 #include 2using
namespace
std;34
#define maxn 10000556
intla, lb, fail[maxn];
7char
a[maxn], b[maxn];89
intmain()
17for (int i = 1, x = 0; i <= la; i++)
21 cout << "
n/a";22
return0;
23 }
KMP演算法 知識點 模板 應用
這裡並不打算去詳細推導kmp的原理,以及精髓。只是整理了一下kmp演算法的模板 應用 理解的關鍵點。kmp演算法最基本的應用就是字串的匹配 給定乙個text串,乙個pattern串,詢問pattern串在text串中是否出現,以及出現幾次 位置等等。class kmpif pattern i pat...
演算法 演算法知識點歸納
1.if flag 等價於.if flag!0 簡寫要弄清含義。2.std ios sync with stdio false 用這個語句,取消cin,cout與stdio的同步,注意不要打錯了。3.在迴圈中盡量不要把迴圈變數直接賦值給某一變數,容易出錯。迴圈中需要判定的變數注意每次是否要初始化。4...
演算法知識點彙總
1.求陣列元素之間相鄰的元素個數或者求字串的長度 指向同乙個陣列的不同元素的兩個指標可以相減,其差便是兩個指標之間相隔的元素個數。例如在乙個字串中,讓乙個指向該串的首元素,讓另乙個指向字串的結束符,兩個指標相減,其差便是字串的長度 2.怎樣判斷兩個指標指向的是陣列的同乙個元素?指標可以互相比較。如指...