• Trie树(字典树)整理


    字典树 (Trie)

    用于存储字符串。树的每条边恰好表示一个字符,每个节点代表从根到该节点的路径所对应的字符串。

    简介与操作实现可见蓝书P82~83。

      Trie字典树很好地利用了前缀,节省了很多空间。

     1 //先说明一下:本代码段的字符串d的下标都是从1开始
     2 inline void insert(char *d)//向Trie树插入字符串d 
     3 {
     4     int l=strlen(d+1),now=0,num;
     5     for(int i=1;i<=l;++i)
     6     {
     7         num=d[i]-'a';//字符化为数字下标 
     8         if(!tree[now][num])//当前节点不存在该字母的边,即该字母还未在当前节点插入过 
     9             tree[now][num]=++cnt;
    10         now=tree[now][num];
    11     }
    12     ed[now]=1;//最后标明一下字符串结尾节点,说明该节点代表了一个已插入过的字符串 
    13 }
    14 
    15 inline int fin(char *d)从Trie树查询字符串d 
    16 {
    17     int  l=strlen(d+1),now=0,num;
    18     for(int i=1;i<=l;++i)
    19     {
    20         num=d[i];
    21         if(!tree[now][num])//不存在对应节点了,说明Trie中没有这个串
    22             return 0;
    23         now=tree[now][num];
    24     }
    25     return ed[now];//查询到最后还要看当前节点是否代表一个插入过Tire树的字符串
    26 }
    操作实现的核心代码

    应用:

    1、前缀查找。

      在Trie树中查找一个字符串的前缀。不管Trie树中插入了多少个字符串,查找的复杂度都是优秀的O(n)(n为当前字符串的长度)。

      还有一种边插边找前缀的方法。如果当前串插入Trie树时没有新建任何节点,那它就是它的末尾节点的子树中所有串的前缀;如果当前串插入Trie树时经过了某个串x的末尾节点,那么x就是当前串的一个前缀。

    2、异或相关。

      将每个数看做二进制的01串。从Trie树中找当前数字异或值最大的数,只要尽可能向与当前边反方向的边走就好。

     1 inline int fin(int a)//从Trie树中找与a异或的结果最大的数,并返回这个结果
     2                      //a为int范围的一个正整数 
     3 {
     4     int ret=0,c,now=1;//这里的Trie数根节点的编号为1 
     5     for(int k=30;k>=0;--k)
     6     {
     7         if((a&(1<<k))^(1<<k))//看下a当前位取反的结果 
     8             c=1;
     9         else
    10             c=0;
    11         if(tree[now][c])//当前点能有a当前位代表边的另一侧方向的边的话,就走那条边 
    12         {
    13             now=tree[now][c];
    14             ret|=1<<k;//维护答案(当前走的与a的当前位不一样的话,答案的当前位就是1,因为是异或) 
    15         }
    16         else//没有的话,有哪条边,就走那条边喽。
    17             //Trie树中至少有一个数的话,一定能一直走下去 
    18             now=tree[now][c^1];
    19     }
    20     return ret;
    21 }
    相关代码
  • 相关阅读:
    hdu 4970 树状数组 “改段求段”
    hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs
    hdu3715 2-sat+二分
    hdu 3639 有向图缩点+建反向图+搜索
    hdu 3072 有向图缩点成最小树形图计算最小权
    hdu 3061 hdu 3996 最大权闭合图 最后一斩
    hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
    hdu 4738 无向图缩点断桥 // 细节坑题
    hdu3452 无向树去掉最小的边集使任何叶子与根不连通 / 最小割
    hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/11808930.html
Copyright © 2020-2023  润新知