zoukankan      html  css  js  c++  java
  • 关于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
    ");
    			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];
    	}
    }




  • 相关阅读:
    欢庆入住博客园
    指定线程所运行的CPU核心
    [GNU/Linux MakeFile] 第一章:概述
    [.NET][编程之美][1.1]C# 实现让CPU占用率曲线听你的指挥 – 可指定运行核心
    vmware workstation 7.1 正式版 序列号 注册机
    linux:设置 linux定时运行命令脚本 (crontab详解)
    守护进程(Daemon)
    Linux下定时执行脚本
    二叉树的遍历(转)
    dup,dup2,fcntl,ioctl用法简述
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6501186.html
Copyright © 2011-2022 走看看