• 关于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];
    	}
    }




  • 相关阅读:
    算法-最大公约数
    算法-最大连续子序列和
    iOS开发-Bug锦囊
    iOS开发-简单抽奖
    iOS开发-UIActionSheet简单介绍
    iOS开发-UIActivityIndicatorView简单使用
    iOS开发-UITextView实现PlaceHolder的方式
    iOS开发-Reachability实时检测Wifi,2G/3G/4G/网络状态
    [转]jsPlumb插件做一个模仿viso的可拖拉流程图
    Python 日期和时间
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6501186.html
Copyright © 2020-2023  润新知