TRIE(字典树)模板

来源:互联网 发布:飞豆打印软件注册码 编辑:程序博客网 时间:2024/05/18 01:08
/*给一个不用指针,用链式前向星写的TRIE,当初只为省空间*/#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#define For(i,a,b) for(register int i=a;i<=b;++i)#define Rep(i,a,b) for(register int i=a;i>=b;--i)const int maxx=5000001;using namespace std;int be[maxx],ne[maxx],to[maxx],e=0,cnt=0;//cnt表示节点编号,e表示边的编号void add(int x,int y){to[++e]=y;ne[e]=be[x];be[x]=e;}struct node{char x;//x:当前节点所存的字符bool vis,end;//vis 是否REPEAT  end是否为名字结尾}trie[maxx];char name[56];void insert(char *s){//插入操作int pos=0,len=strlen(s),i=0,flag;For(i,0,len-1){flag=0;for(int j=be[pos];j;j=ne[j]){int go=to[j];if(trie[go].x==s[i]){//找到已有相同节点,就把位置赋给posflag=1;pos=go;break;}}if(!flag) {add(pos,++cnt); pos=cnt; trie[pos].x=s[i];}//没有找到就新建节点,单向边!if(i==len-1) trie[pos].end=1;//标记结束}}int query(char *s){int pos=0,len=strlen(s),i=0,flag;For(i,0,len-1){flag=0;for(int j=be[pos];j;j=ne[j]){int go=to[j];if(trie[go].x==s[i]){pos=go;flag=1;break;}}if(!flag) return 0;//没找到就返回0if(i==len-1)if(trie[pos].end){//判断是否REPERTif(!trie[pos].vis) {trie[pos].vis=1; return 1;}else return 2;}else return 0;}}int main(){#ifndef ONLINE_JUDGEfreopen("input.in", "r", stdin);freopen("output.out", "w", stdout);#endifint n,m,k;scanf("%d",&n);For(i,1,n){scanf("%s",name);insert(name);}scanf("%d",&m);For(i,1,m){scanf("%s",name);k=query(name);if(k==1) puts("OK");else if(!k) puts("WRONG");else puts("REPEAT");}return 0;}
任意门