Trie树
\(Trie\)树
今天搞了不少的好东西,正好趁热整理一下。
\(Trie\)树:
\(Trie\)树,其实就是一种专门用来存储字符串的树型结构。
其基本代码与链式前向星相似。
能够将建树和查询的复杂度降低到一个非常友善的地步:
void add (char c[]){
int len=strlen(c+1);
int t=0;
for(int i=1;i<=len;i++){
if(!f[t][c[i]-'a']) f[t][c[i]-'a']=++cnt;
t=f[t][c[i]-'a'];
}
cd[t]=1;
}
建树操作。
看吧~与链式前向星特别相似\(qwq\)
以及……
\(Trie\)树的模板题:
\(AC\)代码
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt;
char name[50001],report[500001],vis[500001];
int f[500001][30];
int cd[500001];
void add (char c[]){
int len=strlen(c+1);
int t=0;
for(int i=1;i<=len;i++){
if(!f[t][c[i]-'a']) f[t][c[i]-'a']=++cnt;
t=f[t][c[i]-'a'];
}
cd[t]=1;
}
void check(char c[]){
int len=strlen(c+1);
int t=0;
for(int i=1;i<=len;i++){
t=f[t][c[i]-'a'];
if(!t){
printf("WRONG\n");
return;
}
}
if(!vis[t]&&cd[t]){ printf("OK\n");vis[t]=1;return;}
if(!cd[t]) {printf("WRONG\n");return ;}
if(vis[t]) {printf("REPEAT\n");return;}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",name+1);
add(name);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%s",report+1);
check(report);
}
return 0;
}
另外:洛谷的测试数据特别特别的水。
举个栗子:
对于一个学生:\(asdfo\)
如果老师念了\(asd\)
那么显然我们应该输出\(WRONG\)
但是!!!
我们输出\(REPEAT\)也能$AC
当然我的代码没有这个问题。