對於初學字串的人來說 kmp演算法算是乙個比較難以理解的演算法,但是它在字串匹配問題的效率中是很高的。
核心思想:
匹配過程中 對於每一次失敗的匹配所提供的有用資訊加以利用。首先我們丟擲乙個問題:abcabcabcd和abcabcd進行匹配
匹配到 abcabc a
abcabc d的時候匹配失敗我們可以直接跳轉到
匹配 abcabc a
abc a
即跳轉到它的最大首尾相同的字元子串
給你一段任意字串 求它的所有長度大於2的字首的最大首尾相同的字元子串長度記作ne[想法:len]
,len
ne[len] , len
ne[len
],le
n為字首長度
什麼是首尾相同的字元子串:
如 abcsssacabc 它的首位相同的字元子串為abc 長度為3 並且子串不能是字首本身
對於長度為2的字首來說
如果a [1
]==[
2]
a[1]==[2]
a[1]==
[2] 那麼ne[
2]=1
ne[2] = 1
ne[2]=
1,否則ne[
2]=0
ne[2] = 0
ne[2]=
0;對於長度為3的字首來說
在匹配長度為2的字首匹配成功的基礎上如果 有 $a[2]==a[3] $那麼 ne[
3]=2
ne[3] = 2
ne[3]=
2;如果a [2
]!=a
[3
]a[2] != a[3]
a[2]!=
a[3]
那麼就可以令 匹配串 的序號 j=n
e[2]
j = ne[2]
j=ne[2
] 在匹配長度為2的字首匹配失敗的基礎上–對3的操作如同對長度2的操作
後面的過程類推 可以寫出以下**
void
get_ne()
}
在有了ne[
]nene
陣列的情況下
kmp演算法就很簡單理解了
void
kmp()}
}
#include
#include
#include
#include
#include
using namespace std;
const
int n =
1e4+
10,m =
1e6+10;
int tri[n*55]
[27],idx;
int ne[n*55]
;char ch[m]
;int cnt[n*55]
;queue<
int> q;
void
build()
cnt[p]++;
}void
init()
}}}int
main()
scanf
("%s"
,ch)
;init()
;int ans =0;
for(
int i=
0,j=
0;ch[i]
;i++)}
cout<}return0;
}
ac自動機 匹配最長字首 多模匹配 AC自動機
精確的字串匹配演算法有 單模匹配演算法,比如,kmp bm演算法等 和 多模匹配演算法,比如,wu manber ac演算法等。ac演算法 aho corasick 是kmp演算法向多模式串情形的擴充套件,該演算法使用一種特殊的自動機,即ac自動機。ac自動機由一組模式串p生成,是trie的擴充套件...
AC自動機 多模匹配演算法
寫了個模板題,加強版借鑑大佬的 前置技能kmp 感覺沒啥用主要是思想 字典樹。p3808 模板 ac自動機 簡單版 include include include include include include include include using namespace std typedef ...
kmp與ac自動機
xj比賽做到一道字串題,結果發現想打個字串匹配都只會n 2了,又一次忘記了kmp 想必是當初學這玩意心理陰影面積太大了。這裡再梳理一遍kmp和ac自動機 以便下次再忘了有地方看.kmp 用於處理對於字串s,想知道它在另外某個串哪些位置出現的問題,先做預處理得到乙個失配陣列,這個陣列第i位表示s的前i...