Trie 树

Trie树是一种用于多模式串匹配的数据结构,通过树形结构优化前缀相同的单词查找,提高搜索速度。文章包含Trie树的介绍和模板应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Trie 树

参考资料

介绍

Trie树是一种高级数据结构,用于解决多模式串匹配问题(KMP算法是用以解决单模式串匹配),其主要思想是利用树形结构,(树上除根节点外,每一个节点都对应着一个字符),使得前缀相同的单词共用前缀部分的节点.加快匹配速度.

模板

// 个人倾向于使用数组形式的字典树,动态节点类型不好debug
//对于字符串比较多的要统计个数的,map被卡的情况下,直接用字典树
//很多题都是要用到节点下标来表示某个字符串
const int maxn =2e6+5;//如果是64MB可以开到2e6+5,尽量开大
int sum[maxn]; // 这个在此??
int tree[maxn][30]; // tree[i][j]表示节点i的第j个儿子的节点编号
bool flagg[maxn]; // 表示以该节点结尾是一个单词,换句话说,`flagg[i]==1`表示至少存在一个单词,其结尾节点是i
int tot;//总节点数
// 至于参数,之后也会考虑换成string 类型

// insert_函数几乎不会发生变化,其主要维护 tot,tree[][],sum[],flagg[]
void insert_(char *str)
{
   int  len=strlen(str);
   int root=0;
   for(int i=0;i<len;i++)
   {
       int id=str[i]-'0';
       if(!tree[root][id]) tree[root][id]=++tot;
       sum[tree[root][id]]++; //记录节点访问次数
       root=tree[root][id];
   }
   flagg[root]=true;
}

/* 此函数表示是否存在前缀为str的单词 */
bool find_(char *str)//查询操作,按具体要求改动
{
    int len=strlen(str);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'0';
        if(!tree[root][id]) return false;
        root=tree[root][id];
    }
    return true;
}

/* 此函数返回存在前缀str的单词的个数 */
int find_2(char *str)
{
    int len=strlen(str);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'a';
        if(!tree[root][id]) return 0;
        root=tree[root][id];
    }
    return sum[root];//返回当前字符串结尾节点的访问次数,也就是作为前缀的出现次数
}

/* 此函数返回是否存在单词str */
bool find_3(char *str)
{
    int len=strlen(str);
    int root=0;
    for(int i=0;i<len;i++)
    {
        int id=str[i]-'a';
        if(!tree[root][id]) return true;//该单词没有出现过
        root=tree[root][id];
    }
    if(flagg[root]) return false;//出现过,不再算贡献
    else return true;
}

void init()//最后清空,节省时间
{
    for(int i=0;i<=tot;i++)
    {
       flagg[i]=false;
       for(int j=0;j<10;j++)
           tree[i][j]=0;
    }
   tot=0;//RE有可能是这里的问题
}

题目等之后做题再补上,目前还只会套模板,后续更新带删除版的字典树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值