【22. Trie树】

简介: **用途**- 高效地存储和查找字符串集合的数据结构**主要思想:**- 利用字符串的公共前缀来节约存储空间。很好地利用了串的公共前缀,节约了存储空间。字典树主要包含两种操作,插入和查找。

用途

  • 高效地存储和查找字符串集合的数据结构

主要思想:

  • 利用字符串的公共前缀来节约存储空间。很好地利用了串的公共前缀,节约了存储空间。字典树主要包含两种操作,插入和查找。

例子

  • abc,abb,bc, bca存储在树中

1661153101756.png

  • idx: idx代表树中每一个节点的编号,idx的大小只与插入字典树的先后顺序有关.
  • son[N][26]: 每个son代表一条边,字典树其中1~ N为子节点的父节点的编号,0 ~ 26,其中0代表根节点,1~26代表26个字母。
  • cnt[N]: 以N为节点的单词的结束。

son[上节点编号][下方连接的字母]=下方连接的字母的节点编号
字母a~z对应数字0 ~ 25。

//abc
son[0][0] = 1 son[1][1] = 2 son[2][2] = 3; cnt[3] ++;
//abb
son[0][0] 存在 son[1][1] 存在 son[2][1] = 4 cnt[4] ++;
//bc
son[0][1] = 5 son[5][2] = 6 cnt[6] ++;
//bca
son[0][1] 存在 son[5][2] 存在 son[6][0] = 7 cnt[7] ++;

题目

维护一个字符串集合,支持两种操作:

  1. I x 向集合中插入一个字符串 x;
  2. Q x 询问一个字符串在集合中出现了多少次。

共有 N 个操作,输入的字符串总长度不超过 105,字符串仅包含小写英文字母。

输入格式

第一行包含整数 N,表示操作数。

接下来 N 行,每行包含一个操作指令,指令为 I xQ x 中的一种。

输出格式

对于每个询问指令 Q x,都要输出一个整数作为结果,表示 x 在集合中出现的次数。

每个结果占一行。

数据范围

1 ≤ N ≤ 2∗104

输入样例:

5
I abc
Q abc
Q ab
I ab
Q ab

输出样例:

1
0
1

代码

#include <iostream>
using namespace std;
const int N = 100010;
int cnt[N], son[N][26], idx; //下标是0的点,既是根节点,又是空节点(如果一个节点没有子节点,也会让他指向0)
char str[N];
void insert(char str [])
{   int p = 0;
    for (int i = 0; str[i]; i ++)
    {
        
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++idx;
        p = son[p][u];
        
    }
    cnt[p] ++;
}

int query(char str[])
{
    int p = 0;
    for (int i = 0; str[i]; i ++)
    {
        int u = str[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}

int main()
{
    int n;
    scanf("%d", &n);
    while (n --)
    {
        char op[2];
        scanf("%s%s", op, str);
        if (op[0] == 'I') insert(str);
        else printf("%d\n", query(str));
    }
    return 0;
}
#include <iostream>
using namespace std;
const int N = 100010;
int cnt[N], son[N][26], idx; //下标是0的点,既是根节点,又是空节点(如果一个节点没有子节点,也会让他指向0)

void insert(string str)
{   int p = 0;
    for (int i = 0; i < str.size(); i ++)
    {
        
        int u = str[i] - 'a';
        if (!son[p][u]) son[p][u] = ++idx;
        p = son[p][u];
        
    }
    cnt[p] ++;
}

int query(string str)
{
    int p = 0;
    for (int i = 0; i < str.size(); i ++)
    {
        int u = str[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}

int main()
{
    int n;
    cin >> n;
    while (n --)
    {
        char op;
        string s;
        cin >> op >> s;
        if (op == 'I') insert(s);
        else printf("%d\n", query(s));
    }
    return 0;
}
目录
相关文章
|
6月前
哈夫曼编码和字典树
哈夫曼编码和字典树
47 0
|
6月前
|
存储 C++
leetcode-208:实现 Trie (前缀树/字典树)
leetcode-208:实现 Trie (前缀树/字典树)
50 0
|
存储 自然语言处理 算法
一种好用的树结构:Trie树
一种好用的树结构:Trie树
174 0
一种好用的树结构:Trie树
|
存储 Java
Java数据结构之第十五章、Trie(前缀树/单词查找树)
1.前缀树的概念:前缀树又叫字典树或单词查找树(高效的存储和查找字符串集合的数据结构)。2.3.存储形式:存储的字符串可能:全是 小写字母 或全是 大写字母 或全是 数字 或全是 0和1。它是一棵,每个代表一个,从。字典树的根节点不包含字符,每个子节点代表一个字符,从根节点到任意一个节点所经过的路径上的字符连接起来即为该节点所代表的字符串。每个节点可以存储一个或多个字符串,通常使用一个标志来标记一个节点代表的字符串是否存在。当需要在一组字符串中查找某个字符串时,可以利用字典树来实现高效的查找操作。
75 0
理解前缀树
理解前缀树
60 0
|
存储 机器学习/深度学习 算法
|
存储
前缀树
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
76 0
前缀树
|
机器学习/深度学习 存储 自然语言处理
Trie树
Trie树
105 0
|
存储 算法 Linux
秒懂算法 | 字典树
字典树是一种基础方法,请掌握字典树的静态数组存储方法,它在后缀树、回文树、AC自动机、后缀自动机中都要用到。
153 0
|
存储 自然语言处理 算法
字典树详解
字典树,顾名思义,是关于“字典”的一棵树。即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法)。
169 0
字典树详解