Trie字典树

Trie字典树


Trie是一棵树,有很多节点(是人都知道),每两个节点的边都代表一个字符。例如一个字符串abc

insert

如果进行插入的话,那么,节点编号为0的节点,通过字符a到达节点编号为1的节点;节点编号为1的节点,通过字符b到达节点编号为2的节点;节点编号为3的节点,通过字符c到达节点编号为4的节点。最后,在节点4打上一个标记,也就是说节点4是其中一个字符串的结束位置.
在这道题中,要求的是字符串出现的次数,所以不能简单地用标记数组进行01标记,要存下这个节点是多少个字符串的结束位置。
到此,insert,插入一个字符串的函数就结束了。

Son [父亲的位置] [儿子的名字]=儿子的位置

在这里插入图片描述

query

插入完了,题目还有询问的部分尚未解决
如何询问呢?
其实和插入的思想很像,就是沿着线路进行搜索而已。
当到达某个节点i的时候,如果下一个字符是c,那么就看一下i通过c能到达哪一个节点。如果该节点为空,那么就直接返回0。否则如果遍历完这个要查询的字符串,那么就返回最后这个节点的权值(出现次数)。

题目:Acwing 835.字符串统计

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 100010; 

// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// cnt[]存储以每个节点结尾的单词数量
int son[N][26], idx; 
int cnt[N]; 

//插入字符串
void insert(string s){
    int next_pos = 0; //下一个要插入的层
    for(int i = 0; i < s.size(); i ++)
    {
        int u = s[i] - 'a'; //计算下标;
        if(son[next_pos][u] == 0) son[next_pos][u] = ++idx;
        next_pos = son[next_pos][u];
    }
    cnt[next_pos] ++;
}

//查询字符串出现次数
int query(string s){
    int next_pos = 0;
    for(int i = 0; i < s.size(); i ++)
    {
        int u = s[i] - 'a';
        if(son[next_pos][u] == 0) return 0;
        next_pos = son[next_pos][u];
    }
    return cnt[next_pos];
}

int main(){
    int num;
    cin >> num;
    while(num --){
        string op,b;
        cin >> op >> b;
        if(op == "I") insert(b);
        else if(op == "Q") cout << query(b) << endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值