字符串
大部分字符串的东西都会放在这篇。
待补。
KMP
大体思路:
主串和模式串进行挨个匹配。到了一个不匹配的,找该点前面的最长公共前后缀(且要小于子串长度),然后让前缀跳到后缀的位置。
当前位与主串比较,等于最大公共前后缀长度+1。
\(nxt[i]\) : 当第i位失配时,模式串的第\(nxt[i]\)位与当前位置比较。
code:
const int N=1e6+10;
char s1[N],s2[N];
int l1,l2,nxt[N];
signed main(){
cin>>s1+1;
cin>>s2+1;
l1=strlen(s1+1);
l2=strlen(s2+1);
// nxt[0]=nxt[1]=1;
int pos=0;//模式串
//预处理nxt数组
rep(i,2,l2){
while(pos&&s2[i]!=s2[pos+1]) pos=nxt[pos];//如果不匹配 直到匹配或=0为止
if(s2[pos+1]==s2[i]) ++pos;//如果匹配就更新
nxt[i]=pos;//更新nxt
}
pos=0;
rep(i,1,l1){//同理
while(pos&&s1[i]!=s2[pos+1]) pos=nxt[pos];
if(s2[pos+1]==s1[i]) ++pos;
if(pos==l2) {
cout<<i-l2+1<<'\n';
pos=nxt[pos];
}
}
rep(i,1,l2) cout<<nxt[i]<<" ";
return 0;
}
AC自动机
前置芝士:Trie,KMP,DP(思想。
AC 自动机是一类确定有限状态自动机,这说明它有完整的 DFA 五要素,分别是起点\(s\)(Trie 树根节点),状态集合 \(Q\)(Trie 树上所有节点),接受状态集合 \(F\)(所有以某个单词作为后缀的节点),字符集 \(Σ\)(题目给定)和转移函数 \(δ\)(类似 KMP 求解)。
AC 自动机全称 Aho-Corasick Automaton,简称 ACAM。
Key:
考虑用类似 KMP 的算法求解失配指针:首先令 \(fail_q←fail_{faq}\)。若当前的 \(fail_q\)没有 \(fa_q→q\) 这条(字典树上的)边所表示的字符 \(c\) 的转移,则令 \(fail_q←fail_{failq}\),否则\(fail_q=trans(fail_q,c)\),即字典树上在 \(fail_q\)处添加字符 \(c\) 后到达的状态。若 \(fail_q\)已经指向根,但还是没找到出边,则 \(fail_q\)
最终就指向根。
Code:
int n,cnt;
string s;
struct node{
int fail,son[26],end;
}t[N];
void build(string s){//建立tire树
int l=s.length();
int now=0;
rep(i,0,l-1){
if(t[now].son[s[i]-'a']==0)
t[now].son[s[i]-'a']=++cnt;
now=t[now].son[s[i]-'a'];
}
t[now].end+=1;
}
void Get_fail(){//构造fail
queue<int>q;
rep(i,0,25){
if(t[0].son[i]!=0){//预处理
t[t[0].son[i]].fail=0;//指向根
q.push(t[0].son[i]);
}
}
while(!q.empty()){
int now=q.front();
q.pop();
rep(i,0,25){
if(t[now].son[i]!=0){//存在子节点
t[t[now].son[i]].fail=t[t[now].fail].son[i];//子节点的fail -> 当前节点相同子节点
q.push(t[now].son[i]);
}
else t[now].son[i]=t[t[now].fail].son[i];
}
}
}
void AC(string s){
int l=s.length();
int now=0,ans=0;
rep(i,0,l-1){
now=t[now].son[s[i]-'a'];
for(int nw=now;nw&&t[nw].end!=-1;nw=t[nw].fail){
ans+=t[nw].end;
t[nw].end=-1;
}
}
cout<<ans;
}
signed main(){
n=read();
rep(i,1,n){
cin>>s;
build(s);
}
t[0].fail=0;
Get_fail();
cin>>s;
AC(s);
return 0;
}

浙公网安备 33010602011771号