多字符串存储的Trie树详解
RT,最近刷了一波水题,同时复习了一下Trie树结构,下面进行一个小详解
原理
我们把字符串的一端对齐。然后按照字符位进行树上的更新与插入,目的就是使为了从每个单词节点出发,到根节点结束所形成的一条路径表示原来插入的字符串,鉴于它十分简单,网上资料也很多,这里不再进行赘述
代码
下面贴代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 45
using namespace std;
struct trie{
bool if_word;
int size;
trie* child[10];
trie():size(0),if_word(false){
for(int i=0;i<10;i++)
this->child[i]=NULL;
}
};
trie* head;
int n;
char num[maxn];
bool insert(){
bool f=0;
trie* now=head;
int len=strlen(num);
head->size++;
for(int i=0;i<len;i++){
if(now->child[num[i]-'0']==NULL){
now->child[num[i]-'0']=new trie();
f=1;
}
now->child[num[i]-'0']->size++;
if(i==len-1){
now->child[num[i]-'0']->if_word=true;
}
if(f==0&&now->child[num[i]-'0']->if_word==1){
return false;
}
now=now->child[num[i]-'0'];
}
return true;
}
void init(){
head=new trie();
return;
}
int main(){
/*freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);*/
int T;
scanf("%d",&T);
jump:while(T--){
bool flag=1;
init();
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",num);
if(!flag)continue;
if(!insert()){
flag=false;
}
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}
上面的代码的作用为求出一堆字符串中是否有某一个为另一个的前缀,如果有则输出NO,否则输出YES
细节
大致来说有如下几点:
1.我们要在标记了当前节点是否为单词节点了以后再进行判断与处理
2.我们要将该输入的都输入才行,否则会产生错误
3.每个节点的 size 域可以在插入字符串的时候进行计算与累加
例题
上述代码本身就是一道例题,其余的以后再贴O(∩_∩)O~