算法笔记【图论】字典树
字典树是干什么的
字典树能够记录多个字符串的前缀,能够快速地查找公共前缀,查询单词等操作
实现思路
根节点为空,每个节点都代表着一个字母,每个节点下最多有26个字母节点,类似于下图
具体操作
1 创建数组模拟树int trie[N][30],表示trie[i][j]为节点i的孩子字母为j,下个节点编号为trie[i][j]
和附加信息数组int val[N],表示第i个节点的附加信息
2 插入函数
void insert(string s){
int u = 0;
for(int i=0;i<s.length();i++){
if(trie[u][f(s[i])]==0){
trie[u][f(s[i])] = ++cnt;
}
u = trie[u][f(s[i])];
}
}
例题P2580 于是他错误的点名开始了
AC代码
#include<bits/stdc++.h>
using namespace std;
int f(char c){
return c-'a';
}
int trie[800000][30];
int val[800000];
int cnt = 0;
void insert(string s){
int u = 0;
for(int i=0;i<s.length();i++){
if(trie[u][f(s[i])]==0){
trie[u][f(s[i])] = ++cnt;
}
u = trie[u][f(s[i])];
}
}
void ask(string s){
int u = 0;
for(int i=0;i<s.length();i++){
if(trie[u][f(s[i])]==0){
cout<<"WRONG"<<endl;
return;
}
u = trie[u][f(s[i])];
// cout<<u<<" ";
}
if(val[u]==0) {
cout<<"OK"<<endl;
val[u]++;
}
else {
cout<<"REPEAT"<<endl;
}
return ;
}
int main(){
int n;
cin>>n;
memset(trie,0,sizeof(trie));
memset(val,0,sizeof(val));
while(n--){
string t;
cin>>t;
insert(t);
}
cin>>n;
while(n--){
string a;
cin>>a;
ask(a);
}
return 0;
}
因为数组开小了,wrong了很多次。。