所谓trie,其实就是一棵树,不过它的节点是一个字符。
手动建立一棵trie,用来做模型
这就是一棵trie,是不是有点想法了?
设trie[i,j]=k表示编号为i的节点的儿子是标号为j的节点的编号
编号和标号是不一样的
先说标号,所谓标号
例如有26个小写字母,那么标号就是1~26,
如果有52个大小写字母,标号就是1~52,反正多一种就多给它个标号。
然后是编号,编号是一个动态开点的过程,举个栗子
假设有
bee这个单词,
我们将它插入到trie里面去,
root是0号节点
bee
第一个字符是‘b’,标号为2(ord(‘b’)-96也就是ASCII码-96)
trie[0,2]=0,也就是还没有这个节点
给它建立一个节点
tot+1=1
trie[0,2]=tot
跑到这个节点去
第二个字符是‘e’,标号为5
tot+1=2
trie[1,5]=tot
跑到这个节点去
第三个字符同理
tot+1=3
trie[2,5]=tot
假设再来一个bear
前面‘be’都是有的,所以跑到了编号为2的节点
这时又发现第三个字母‘a’又没了
tot+1=4
trie[2,4]=tot
以下同理,整理出来就是
过程很清晰,现在给出代码
procedure make(x,t:longint);
var
ch:char;
begin
if(x=length(s[i]))then
begin
bz1[t]:=true;
exit;
end;
ch:=s[i][x+1];
if(trie[t][ord(ch)-96]=0)then
begin
inc(tot);
trie[t][ord(ch)-96]:=tot;
f[tot]:=ch;
end;
make(x+1,trie[t][ord(ch)-96]);
end;
f[tot]表示编号为tot的点所代表的字符
bz1[t]表示编号为t的点是不是一个字符串的终止点
然后我们就有了一棵trie
有什么用呢?
第一个用处是看某一个字符串在不在一堆字符串里
这个很明显嘛,顺着trie跑一遍,跑到底看看是不是一个字符串的终止点
procedure search(x,t:longint);
var
ch:char;
begin
if(x=length(s1))then
begin
if(bz1[t])then bz:=true
else bz:=false;
exit;
end;
ch:=s1[x+1];
if(trie[t][ord(ch)-96]=0)then
begin
bz:=false;
exit;
end;
search(x+1,trie[t][ord(ch)-96]);
end;
然后还有一种就是判断一个前缀是多少个串的前缀,大致是一样的,就是每走一步都判断一下是不是一个串的结尾。
另外还有求xor最大值也可以用trie,总而言之,想象力有多大,trie就有多少用处。