Trie

简介

其实就是一颗树,好多题目是26叉树

操作

如果我们有字符串 cal c a l cat c a t app a p p aply a p l y hh h h ;
我们可以先构建一颗这样的树 ( 画风诡异,见谅:
这里写图片描述

小性质

1、字典树用边表示字母
2、有相同前缀的单词公用前缀节点,那我们可以的得出每个节点最多有26个子节点(在单词只包含小写字母的情况下)
3、整棵树的根节点是空的。便于插入和查找

insert操作


我们设数组 node[i][j]=k n o d e [ i ] [ j ] = k ,表示编号为 i i 的节点的第j个孩子是编号为 k k 的节点。

其实大家应该清楚了。

CODE

inline void insert(char s[])
{
    int root=0,n;
    n = strlen(s);
    for(int i=0;i<n;i++)
    {
        int x = s[i] - 'a';
        if(!node[root][x]) node[root][x] = ++cnt;
        root = node[root][x]; res[root] ++;
    }
}

询问

其实也差不多:

CODE

inline int Search(char s[])
{
    int root=0,n;
    n = strlen(s);
    for(int i=0;i<n;i++)
    {
        int x = s[i] - 'a';
        if(!node[root][x]) return 0;
        root = node[root][x]; 
    }
    return res[root];
}

1.如果是查询某个单词的话,我们用bool变量 v[i]表示节点i是否是单词结束的标志。

那么最后return的是v[root],所以在插入操作中插入完每个单词是,要对单词最后一个字母的v[i]置为true,其他的都是false

2、如果是查询前缀出现的次数的话,那就在开一个sum[],表示位置i被访问过的次数,

那么最后return的是sum[root]

这里前缀的次数是标记在前缀的最后一个字母所在位置的后一个位置上。

练手题:

HDU 1251 统计难题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值