【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 (前缀树/字典树)
51 0
|
存储 自然语言处理 算法
一种好用的树结构:Trie树
一种好用的树结构:Trie树
176 0
一种好用的树结构:Trie树
理解前缀树
理解前缀树
62 0
|
存储 机器学习/深度学习 算法
|
存储
前缀树
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
76 0
前缀树
|
机器学习/深度学习 存储 自然语言处理
Trie树
Trie树
106 0
|
存储 算法 Linux
秒懂算法 | 字典树
字典树是一种基础方法,请掌握字典树的静态数组存储方法,它在后缀树、回文树、AC自动机、后缀自动机中都要用到。
154 0
|
存储 自然语言处理 算法
字典树详解
字典树,顾名思义,是关于“字典”的一棵树。即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法)。
169 0
字典树详解
|
Java C++
字典树(前缀树)
字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
110 0