字典树(Trie树)

简介: 字典树

目录

题目1

代码

题目2

代码

🍔🍔🍔代码分析

🍔Trie树🍔

用处:高效地存储字符串集合的数据结构

概述:就是一个树状结构的存储方式,使用二维数组来存储,其中包含了父结点和子结点,从上向下开始遍历,看是否能够找到对应的结点,从而判断能否找到对应的字符串

存储方法(注意标记结束结点)

image.png图像来源:AcWing 835. Trie字符串统计 - AcWing

下面的结点都是新开辟的结点,u代表字母,来确定结点的具体位置

12.png

不知道为什么,这个题在y总的课里面是基础算法,但是在洛谷上却是普及+的

那么下面就先给出两道简单的(可以作为模板使用)

13.1.png 

回归正题

题目1

[NOI2000]单词查找树 (nowcoder.com)

13.2.png

13.3.png

代码

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int son[N][26],cnt[N],idx;
void insert(string s)
{
    int p=0;
    for(int i=0;i<s.size();i++)
    {
        int u=s[i]-'A';
        if(!son[p][u]) son[p][u]=++idx;
        p=son[p][u];
    }
    cnt[p]++;
}
int main()
{
    string s;
    while(cin>>s)
    {
        insert(s);
    }
    cout<<idx+1<<endl;
    return 0;
}

while(cin>>s)

边输入边循环,直到输入到结束符EOF为止

题目2

835. Trie字符串统计 - AcWing题库

13.4.png

代码

#include <iostream>
using namespace std;
const int N = 100010;
int son[N][26], cnt[N], idx;
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)//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 == 'I') insert(str);//op[0]
        else printf("%d\n", query(str));
    }
    return 0;
}

🍔🍔🍔代码分析

⭐代码里面的int son[N][26],不能写成int  son[N][N],

因为N就很大了,如果写成son[N][N],相当于存储的是N * N,会爆int

⭐int son[N][26];

son[][]存储子节点的位置,因为有26个字母,所以分支最多26条

⭐ int u = str[i] - 'a';

用来记录每个字母的位置是什么

⭐insert()

    if (!son[p][u]) son[p][u] = ++ idx;    p = son[p][u];

如果不存在这个结点不存在它的儿子的话,就创建一个结点,它的值为下一个结点的位置上的值

否则  使 p 指针指向下一个位置

相当于:有路的话,就走下去(idx++),否则建一条路也要走下去(p)

    query()

    if (!son[p][u]) return 0;   p = son[p][u];

如果不存在这个结点的话,就是没有查询到,就要返回0(return 0)

否则  使 p 指针指向下一个位置

⭐cnt[]存储以某节点结尾的字符串个数(同时也起标记作用)

cnt[p]++:表示以这个结点结尾的字符串的个数+1

return cnt[p]; 返回字符串出现的次数

⭐++idx

当前插入的结点是哪一个,加入新的结点就用++idx分配出一个下标

Code over!

相关文章
|
6月前
哈夫曼编码和字典树
哈夫曼编码和字典树
47 0
|
6月前
|
存储 C++
leetcode-208:实现 Trie (前缀树/字典树)
leetcode-208:实现 Trie (前缀树/字典树)
50 0
理解前缀树
理解前缀树
60 0
|
存储
前缀树
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
76 0
前缀树
|
机器学习/深度学习 存储 自然语言处理
Trie树
Trie树
105 0
|
存储 算法 Linux
秒懂算法 | 字典树
字典树是一种基础方法,请掌握字典树的静态数组存储方法,它在后缀树、回文树、AC自动机、后缀自动机中都要用到。
153 0
|
存储 自然语言处理 算法
字典树详解
字典树,顾名思义,是关于“字典”的一棵树。即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法)。
169 0
字典树详解
|
Java C++
字典树(前缀树)
字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。
110 0
|
存储
【22. Trie树】
**用途** - 高效地存储和查找字符串集合的数据结构 **主要思想:** - 利用字符串的公共前缀来节约存储空间。很好地利用了串的公共前缀,节约了存储空间。字典树主要包含两种操作,插入和查找。
106 0
【22. Trie树】
|
存储 C++
【LeetCode208】实现Trie(前缀树)
这里的前缀树,即“二十六叉树”,但是对于每个结点(对象),我们可以隐性存储一个字符——每个结点(对象)含有一个size为26的指针数组。接着就从根结点开始遍历判
117 0
【LeetCode208】实现Trie(前缀树)