字典树
\(Trie\) 树
基本概念:
\(trie\) 主要是用来存放字符串的,每一个节点表示一个字符,每个 \(node\) 都表示一个根节点.
就像这样:插入 \(see,pain,pand,dog,trie\) (可以得出一个性质就是如果全是小写字母,每个根节点最多有\(26\)个根节点)
相关代码:
#include<bits/stdc++.h>
using namespace std;
char str[10005][15];//读入
int trie[10005][26],tot=1;
bool end[10005];
void insert(char* str){
int len=strlen(str),p=1;
for(int k=0;k<len;k++){
int ch=str[k]-'a';
if(trie[p][ch]==0)
trie[p][ch]=++tot;//做标记
p=trie[p][ch];//p指向地址
}
end[p]=true;//这个单词被读入过
}
bool search(char *str){
int len=strlen(str),p=1;
for(int k=0;k<len;k++){
p=trie[p][str[k]-'a'];//遍历搜索
if(p==0)
return false;//不存在
}
return true;//存在,为子串
}
int main(){
int n;
cin>>n;
memset(end,false,sizeof(end));
for(int i=1;i<=n;i++) {
cin>>str[i];
insert(str[i]);
}
search();//未写完
return 0;
}
其中,\(p\) 作为指针起初指向根节点,扫描 \(str\) 中的每一个字符 \(c\) :
-
若 \(p\) 的 \(c\) 字符指针指向一个已经存在的节点 \(q\) ,则令 \(p=q\)
-
若 \(p\) 的 \(c\) 字符指向为空,则新建一个节点 \(q\),令 \(q\) 的 \(c\) 字符指向 \(q\) ,然后令 \(p=q\);
当 \(str\) 中的每一个字符都扫描完毕时,在节点 \(p\) 上标记它是一个字符串的末尾。
用处:
-
多条字符串读入比较
-
运用于后缀数组,后缀自动机
不关注的有难了😠😠😠https://b23.tv/hoXKV9