字典树: 提供多个单词,每次查找一个单词,这时可以用字典树。查询1次的复杂度为O(m),m为单词长度。
实现: 举个例子,要记录trie单词。起初添加一个虚根节点。每个节点有字母表数的子节点(如全是小写就有26个子节点),初始为0,表示没有这个子节点。记录trie,那么虚根节点的son[‘t’-‘a’]=1,end=0,表示没有到达单词结尾。然后t节点的son[‘r’-‘a’]=1…以此类推,到e时记录end=1。
查询时就一次看有没有子节点以及最后end是否为1,若都满足,则存在此单词。
应用:
1.字符串的快速检索
2.字符串排序
3.最长公共前缀
4.自动匹配前缀显示后缀
例题:于是他错误的点名开始了
//trie字典树
#include<bits/stdc++.h>
#define REPEAT 2
#define WRONG 3
#define MAXN 1000005
using namespace std;
struct TRIE
{
int end=0;
int son[27];
int repeat=0;
};
TRIE node[MAXN];
int cnt=0;
int n,m;
int Save(string &s){
int nowNode=0;
for(int i=0;i<s.size();i++){
if(node[nowNode].son[s[i]-'a']==0){
cnt++;
node[nowNode].son[s[i]-'a']=cnt;
}
nowNode=node[nowNode].son[s[i]-'a'];
}
node[nowNode].end=1;
return 0;
}
int Check(string &s){
int nowNode=0;
for(int i=0;i<s.size();i++){
if(node[nowNode].son[s[i]-'a']==0)return WRONG;
nowNode=node[nowNode].son[s[i]-'a'];
}
if(node[nowNode].repeat==0){
node[nowNode].repeat=1;
return 0;
}
return REPEAT;
}
int main()
{
cin>>n;
string s;
for(int i=1;i<=n;i++){
cin>>s;
Save(s);
}
cin>>m;
int jug;
for(int i=1;i<=m;i++){
jug=0;
cin>>s;
jug=Check(s);
if(jug==0){cout<<"OK"<<endl;}
if(jug==WRONG){cout<<"WRONG"<<endl;}
if(jug==REPEAT){cout<<"REPEAT"<<endl;}
}
return 0;
}