关于Trie KMP AC自动机

个人认为trie,KMP,AC自动机是思想非常明确的,AC自动机的性质是与KMP算法的思想类似的(失配后跳转)

而KMP是线性的,AC自动机是在tire树上跑KMP,为方便那些不会用指针的小朋友(我也不会。。。。)

我的tire树,kmp算法的next,AC自动机的fail全是用数组实现的!!!!(还有谁???!!!)

所以

上板子

1.KMP

2.TRIE

3.AC自动机

void make() {
	nxt[1]=0;
	for(int i=2; i<=len1; i++) {
		int j=nxt[i-1];
		while(j>0 && s[i]!=s[j+1])j=nxt[j];
		if(s[i]==s[j+1])nxt[i]=j+1;
		else nxt[i]=0;
	}
	return;
}
void kmp(int len){
	int j=0;
	for(int i=1;i<=len1;++i){
		while(j&&s[j+1]!=s[i])j=nxt[j];
		if(s[j+1]==s[i])j++;
		if(j>=len)tot++,j=nxt[j];
	}
}
struct data {
    int num[28];
	int cnt;
} node[1000001];
char s[100000];
void build(char*str) {
	int now=0;
	while(*str) {
		int k=int(*str-'a');
		if(!node[now].num[k])Au++,node[now].num[k]=Au;
		now=node[now].num[k],node[now].cnt++;
		str++;
	}
}
void print(char*str) {
	int now=0;
	while(*str) {
		int k=int(*str-'a');
		if(!node[now].num[k]) {
			printf("0\n");
			return;
		}
		now=node[now].num[k];
		str++;
	}
}

struct data{
	int num[27],id;
}trie[10001];
queue<int>bfs;
int fail[10001];
int n,tot,len;
int ans[10001];
char s[10001][51];
char t[10000001];
void add(int q){//建一棵神奇的字典树
	int now=0;
	int head=0;
	while(head!=len){
		int k=int(s[q][head]-'a');
		if(!trie[now].num[k])trie[now].num[k]=++tot;
		now=trie[now].num[k];
		if(head==len-1){trie[now].id=q;break;}
		head++;
	}
}
void bbfs(){
	bfs.push(0);
	while(!bfs.empty()){
		int w=bfs.front();
		for(int i=0;i<=25;++i)if(trie[w].num[i]){//若有
			int u=trie[w].num[i];
			int fa=fail[w];
			while((fa)&&(trie[fa].num[i]==0))fa=fail[fa];//如果父亲的fail无其相应字母子节点,一直跳下去直到根节点 
			if((trie[fa].num[i]!=u)&&(trie[fa].num[i]))//不等于本身 
			fail[u]=trie[fa].num[i];
			bfs.push(u);//入队 
		}
		bfs.pop();//队首元素出队 
	}
}
void make(){
	int now=0;
	for(int i=0;i<len;++i){
		int k=int(t[i]-'a');
		while(!trie[now].num[k]&&now!=0)now=fail[now];
		now=trie[now].num[k];
		int KMP=now;//根据fail数组性质,要一直while下去!!!直至根节点 
		while(KMP)ans[trie[KMP].id]++,KMP=fail[KMP];
	}
}




posted @ 2017-01-20 09:20  QYP_2002  阅读(134)  评论(0编辑  收藏  举报