关于Trie KMP AC自动机

来源:互联网 发布:软件开发语言培训 编辑:程序博客网 时间:2024/05/21 04:19

个人认为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];}}




2 1
原创粉丝点击