字典树 为学自动机作准备
简单分析原理:当树为空时,sz=1,我们去插入“abd”,此时u=0,c='a'-'a'=0,
trie[u=0][c=0]=0,因此在u=0结点插入c=0这个子结点,trie[u=0][c=0]=sz++ =1;
sz=2;然后往下个结点走u=trie[u=0][c=0]=1,c=‘b’-‘a’=1;此时发现trie[u=1][c=1]=0,
因此我们又要新建子结点trie[u=1][c=1]=sz++ =2,sz=3;往下走u=trie[u=1][c=1]=2,c='d'-'a'=3,
此时又发现trie[u=2][c=3]=0,又要新建结点u=trie[u=2][c=3]=sz++ =3,sz=4;此时我们另val[u=3]="终点标志"
如果我们再加入“abe”会怎样呢?u=0,c=’a‘-’a‘=0,trie[u=0][c=0]=1;
我们只需沿着走,u=trie[u=0][c=0]=1,c='b'-'a'=1;我们发现trie[u=1][c=1]=2,存在了,又只需沿着走,
u=trie[u=1][c=1]=2,c='e'-'a'=4,我们发现trie[u=2][c=4]结点不存在,就新建该结点咯,
u=tire[u=2][c=4]=sz++ =4,sz=5;此时我们另val[u=5]="终点标志"
估计在纸上画画就可以知道是如何插入新字符串了吧!!
接下来我们看如何查询
首先我们查询“ab”是否存在:u=0,c='a'-'a'=0;u=trie[u=0][c=0]=1;往下走,u=1,c='b'-'a'=1,tire[u=1][c=1]=2,可惜val[u=1]没有“终点标志”,
而字符串搜到这已经结束,返回val[u=1]="不存在" orz!!
我们再来查“abd”是否存在,接着上面,u=2,c='d'-'a'=3,trie[u=2][v=3]=3,u=3,此时val[u=3]有“终点标志”,“abd”存在
#define idx(c) c-'a' void init() {//sz为结点总数 //初始化只有一个根结点 sz=1; memset(trie[0],0,sizeof(trie[0])); } //插入字符串s,附近信息为v void insert(char *s,int v) { u=0; n=strlen(s); for(i=0;i<n;i++) { c=idx(s[i]); if(!trie[u][c])//结点不存在 {//结点u保存编号为c的子节点 memset(trie[sz],0,sizeof(trie[sz])); val[sz]=0;//不存在, trie[u][c]=sz++;//新建结点 } u=trie[u][c];//往下走 } val[u]=v;//字符串的最后一个字符放假信息为 } int query(char *s) { n=strlen(s); u=0; for(i=0;i<n;i++) { c=idx(s[i]); //结点u不存在返回0 if(!trie[u][c])return 0; u=trie[u][c];//往下走 } return val[u]; }
浙公网安备 33010602011771号