社区讨论
关于AC自动机 数组写法的疑惑
P3808AC 自动机(简单版)参与者 6已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mi7w0ib6
- 此快照首次捕获于
- 2025/11/21 04:32 4 个月前
- 此快照最后确认于
- 2025/11/21 04:32 4 个月前
询问路过的大佬,为啥数组模拟指针写法会有差别,问题请看代码注释行。(第44行)
CPP#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 2*1e6+9; // 2*le6+9 == 2000009;
int trie[maxn][26];
int count[maxn];
int fail[maxn];
int cnt = 0;
void insertwords(string s){
int root = 0;
for(int i=0;i<s.size();i++){
int next = s[i] - 'a';
if(!trie[root][next])trie[root][next] = ++cnt;
root = trie[root][next];
}
count[root]++;
return ;
}
void getfail(){
queue <int>q;
for(int i=0;i<26;i++){
if(trie[0][i]) q.push(trie[0][i]),fail[trie[0][i]] = 0;
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i=0;i<26;i++){
if(trie[now][i]){
q.push(trie[now][i]);
fail[trie[now][i]] = trie[fail[now]][i];
}
else trie[now][i] = trie[fail[now]][i];//这一句为什么不存在要指向父节点失败指针的子节点???
}
}
}
int query(string s){
int ans = 0,now = 0;
for(int i=0;i<s.size();i++){
now = trie[now][s[i]-'a'];
for(int j=now;j&&count[j]!=-1;j=fail[j]){
ans += count[j];
count[j] = -1;
}
}
return ans;
}
//void init(){
// memset(trie,0,sizeof(trie));
// memset(fail,0,sizeof(fail));
// memset(count,0,sizeof(count));
// cnt = 0;
//}
int main(){
// freopen("123.txt","r",stdin);
// int T;
// cin>>T;
// while(T--){
// init();
int n;
string s;
cin>>n;
for(int i=0;i<n;i++){
cin>>s;
insertwords(s);
}
fail[0] = 0;
getfail();
cin>>s;
cout<<query(s)<<endl;
// }
return 0;
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...