【模版】trie树


trie树


字符串树,多叉树。
每个结点保存的是单个字符,结点按从小到大的顺序编号。
对有公共前缀的若干组字符串,公共部分不用建立多余结点。
有插入和查询两种操作。代码很好记也很好理解。


算法流程:
整型二维数组 t r i e [ 最 大 字 符 数 量 ] [ 字 符 种 类 数 量 ] trie[最大字符数量][字符种类数量] trie[][] 。赋值 为 结点数。

插入:
对于要插入的字符串 S S S。从前往后处理:判断当前字符有没有被记录过,如果没有被记录,则增加结点并记录(如果被记录过,即与之前插入的字符串有公共前缀,则不用增加结点)。然后跳到下一个结点处理下一个字符。
字符串 S S S 的最后一个字符对应结点编号一定要标记,表示当前字符串结束。

void Insert()
{
    char key[1100];
    scanf("%s",key);
    int len = strlen(key), k = 0;
    for(int i = 0; i < len; i++)
    {
        int c = key[i] - 'a';
        if(!trie[k][c]) trie[k][c] = ++t;
        k = trie[k][c];
    }
    flg[k] = 1;
}

查询:
同插入一样,对字符串 S S S 从前往后处理,判断当前位置的字符有没有提前被编号,如果没有则说明字符串 S S S 尚未被插入。如果有被编号,则挪动至下一个结点继续查找下一个字符。
查询到最后一个字符时,需要判断当前的结点是否是 之前插入的字符串的结尾字符。(防止出现 当前查询的字符串 是 之前插入字符串的前缀的情况)

下列代码为例题的代码。

int Query()
{
    char key[1100];
    scanf("%s",key);
    int len = strlen(key), k = 0;
    for(int i = 0; i < len; i++)
    {
        int c = key[i] - 'a';
        if(!trie[k][c]) return 0;
        k = trie[k][c];
    }
    if(flg[k] == 0) return 0;
    cnt[k]++;
    return cnt[k];
}

例题:于是他错误的点名开始了
其他trie树题目:
[USACO08DEC]Secret Message G
[TJOI2010]阅读理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值