社区讨论

关于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 条回复,欢迎继续交流。

正在加载回复...