TRIE(字典樹)模板
阿新 • • 發佈:2019-01-29
任意門/* 給一個不用指標,用鏈式前向星寫的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]){ //找到已有相同節點,就把位置賦給pos flag=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; //沒找到就返回0 if(i==len-1) if(trie[pos].end){ //判斷是否REPERT if(!trie[pos].vis) {trie[pos].vis=1; return 1;} else return 2; } else return 0; } } int main(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("output.out", "w", stdout); #endif int 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; }