Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >trie树(字典树)-HDU1251

trie树(字典树)-HDU1251

作者头像
ACM算法日常
发布于 2018-08-07 11:41:03
发布于 2018-08-07 11:41:03
1.2K00
代码可运行
举报
文章被收录于专栏:ACM算法日常ACM算法日常
运行总次数:0
代码可运行

trie树的实现比较简单。它使在字符串集合中查找某个字符串的操作的复杂度降到最大只需O(n),其中n为字符串的长度。trie是典型的将时间置换为空间的算法,好在ACM中一般对空间的要求很宽松。trie的原理是利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。 它具有以下性质:

  • 根结点不包含任何字符信息;
  • 如果字符的种数为n,则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,还没有想到好点的办法避免);
  • 查找,插入复杂度为O(n),n为字符串长度。

举一个例子,给50000个由小写字母构成的长度不超过10的单词,然后问某个公共前缀是否出现过。如果我们直接从字符串集中从头往后搜,看给定的字符串是否为字符串集中某个字符串的前缀,那样复杂度为O(50000^2),这样显然会TLE。又或是我们对于字符串集中的每个字符串,我们用MAP存下它所有的前缀。然后询问时可以直接给出结果。这样复杂度为O(50000*len),最坏情况下len为字符串最长字符串的长度。而且这没有算建立MAP存储的时间,也没有算用MAP查询的时间,实际效率会更低。但如果我们用trie的话,当查询如字符串abcd是否为某字符串的前缀时,显然以b,c,d....等不是以a开头的字符串就不用查找了。实际查询复杂度只有O(len),建立trie的复杂度为O(50000).这是完全可以接受的。

如给定字符串集合abcd,abd,cdd,efg,hij,hi六个字符串建立的trie tree如下图所示:

查找一个字符串时,我们只需从根结点按字符串中字符出现顺序依次往下走。如果到最后字符串结束时,对应的结点标记为红色,则该字符串存在;否则不存在。插入时也只需从根结点往下遍历,碰到已存在的字符结点就往下遍历,否则,建立新结点;最后标记最后一个字符的结点为红色即可。同时我们看到,如果字符的种类为n,则需要结点的个数为n级数。

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1251题目和我上面举的例子差不多,是说给定一个字符串集合,然后每次询问时给出一个字符串,问以该字符串为前缀的字符串在集合中有多少个。先给个用MAP版本的,限时2000MS的题目,用MAP,1750MS,险过。

代码示例

map版本的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
    int i,j,k,len;
    string str;char temp[15],temp1[15];
    map <string,int> mymap;
    while(gets(temp))
    {
        if(temp[0]=='\n') break;
        len=strlen(temp);
        if(len==0) break;
        for(i=0;i<len;i++)//求出某个字符串的所有前缀,并用MAP存起来
        {
            for(j=0;j<=i;j++) temp1[j]=temp[j];temp1[j]='\0';
            str.assign(temp1);
            mymap[str]++;
        }
    }
    while(scanf("%s",&temp)!=EOF)
        cout<<mymap[temp]<<endl;//此时直接输出结果即可
    return 0;
}

用MAP的特点是代码短,思路简单,很容易实现,但耗时大。下面给出trie版本的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
using namespace std;

const int kind=26;//字母种类

struct Treenode//树的结点结构
{
    int count;//这个附加变量在本题中记录遍历到该结点形成的字符串出现的次数,在不同题中可记录不同的内容。
    Treenode *next[kind];//指向儿子结点
    Treenode()//每个结点的初始化
    {
        count=1;
        for(int i=0;i<kind;i++)
            next[i]=NULL;
    }
};

void insert(Treenode *&root,char *word)//向以root为根结点的树中插入串word
{
    Treenode *location=root;
    int i=0,branch=0;

    if(location==NULL) {location=new Treenode();root=location;}

    while(word[i])
    {
        #这里根据当前字符的“值”索引它的子结点位置
        branch=word[i]-'a';
        #如果该字符存在,串数量加1
        if(location->next[branch]) location->next[branch]->count++;
        #如果不存在,建新结点
        else location->next[branch]=new Treenode();
        #查找字符串的下一个字符
        i++;
        location=location->next[branch];
    }
}
#查找,与插入类似
int search(Treenode *root,char *word)
{
    Treenode *location=root;
    int i=0,branch=0,ans;

    if(location==NULL) return 0;

    while(word[i])
    {
        branch=word[i]-'a';
        if(!location->next[branch]) return 0;
        i++;
        location=location->next[branch];
        ans=location->count;
    }
    return ans;
}
int main()
{
    char word[10];
    char ask[10];
    Treenode *root=NULL;
    while(gets(word)) 
    {
        if(word[0]=='\0') break;
        insert(root,word);
    }
    while(gets(ask))
        cout<<search(root,ask)<<endl;
    return 0;
}

上述代码中插入和查找可当模板来用了

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
剑指Offer——Trie树(字典树)
Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
全栈程序员站长
2022/10/03
1K0
剑指Offer——Trie树(字典树)
Trie树:应用于统计和排序
      Trie树,又称单词查找树、字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
黄规速
2022/06/30
8930
Trie树:应用于统计和排序
Trie树的原理及应用
在做用户 query 理解的过程中,有许多需要使用词典来”识别”的过程。在此期间,就避免不了使用 Trie 树这一数据结构。
呼延十
2019/12/19
1.1K0
Trie树(字典树) [模板]------------Five-菜鸟级
  又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
Fivecc
2022/11/21
7290
Trie树(字典树) [模板]------------Five-菜鸟级
【图解算法】模板+变式——带你彻底搞懂字典树(Trie树)
接下来将对经典的字典树进行代码实现;接着做几个变体题目深入理解字典树的强大;最后回到日常生活,瞧瞧字典树怎样融入到了我们的生活之中 >_<
全栈程序员站长
2022/10/04
1.4K0
【图解算法】模板+变式——带你彻底搞懂字典树(Trie树)
Trie树分析
Trie树 Trie树介绍 Trie,又称单词查找树或键树,是一种树形结构。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 它有3个基本性质: 1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。 2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。 3.每个节点的所有子节点包含的字符都不相同。 Trie中每个节点有一个特殊标记作为结束符号,通过该标记可以判断当前节
汤高
2018/03/28
1.2K0
Trie树分析
Trie树
这周将Trie树看了一下下面进行总结 概念:Trie,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本
用户1624346
2018/04/11
7860
Trie树
HDU3460 (字典树)
The contest is beginning! While preparing the contest, iSea wanted to print the teams’ names separately on a single paper. Unfortunately, what iSea could find was only an ancient printer: so ancient that you can’t believe it, it only had three kinds of operations:
dejavu1zz
2020/10/23
3050
三分钟基础:什么是 trie 树?
为什么说非典型呢?因为它和一般的多叉树不一样,尤其在结点的数据结构设计上,比如一般的多叉树的结点是这样的:
帅地
2019/12/05
9920
三分钟基础:什么是 trie 树?
Trie树
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
全栈程序员站长
2022/07/14
2760
Trie树:字符串频率统计排序
题目:一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
Tim在路上
2020/08/04
1.5K0
一种好用的树结构:Trie树
在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
致Great
2022/05/13
5920
一种好用的树结构:Trie树
字典树 Krains 2020-09-01
当然还有其他的数据结构,如哈希表,使我们能够在字符串数据集中搜索单词。为什么我们还需要 Trie 树呢?尽管哈希表可以在 O(1) 时间内寻找键值,却无法高效的完成以下操作: 找到具有同一前缀的全部键值。
Krains
2020/09/10
4170
Trie(字典树、前缀树)
  Trie是一个多叉树,Trie专门为处理字符串而设计的。使用我们之前实现的二分搜索树来查询字典中的单词,查询的时间复杂度为O(logn),如果有100万(220)个单词,则logn大约等于20,但是使用Trie这种数据结构,查询每个条目的时间复杂度,和一共有多少个条目无关!时间复杂度为O(w),w为被查询单词的长度!大多数单词的长度小于10。   Trie将整个字符串以字母为单位,一个一个拆开,从根节点开始一直到叶子节点去遍历,就形成了一个单词,下图中的Trie就存储的四个单词(cat,dog,deer,panda)
程序员波特
2024/01/19
2480
Trie(字典树、前缀树)
数据结构(12)-- 前缀树(字典树、Trie)
可以用来提取出表中所有以“ABC”开头的数据,但是数据表浩如烟海,你总不能让我去遍历吧!!!
看、未来
2021/09/18
7850
字典树概念与题型解析
这次讲一个不经常被人提起的数据结构 - 字典树,虽说知名度不高,但是这个数据结构可以解决其他数据结构所不能解决,或者是比较难解决的问题,而且性能方面,相对于其他的功能类似的数据结构会更优,文章会从概念与基本实现,性能分析,题型解析三大方向来介绍字典树。
五分钟学算法
2019/10/18
6410
从Trie树到双数组Trie树
Trie树 原理 又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,能在常数时间O(len)内实现插入和查
JadePeng
2018/03/12
3.3K0
从Trie树到双数组Trie树
Trie树的基本原理与实现以及改进
本文介绍了关于Trie树的基本原理与实现,维基百科中的说明如下:trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
大学里的混子
2018/11/08
1.5K0
数据结构之Trie字典树
Trie 树,也叫“字典树”或“前缀树”。顾名思义,它是一个树形结构。但与二分搜索树、红黑树等不同的是,Trie 树是一种多叉树,即每个节点可以有 m 个子节点。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
端碗吹水
2021/01/29
8810
TRIE(2)
 其中MAX_NODE是trie中最大能存储的节点数目,CHARSET是字符集的大小,k是当前trie中包含有多少个节点。Triei的值是0表示trie树中i号节点,并没有一条连出去的边,满足边上的字符标识是字符集中第j个字符(从0开始);triei的值是正整数x表示trie树中i号节点,有一条连出去的边,满足边上的字符标识是字符集中第j个字符,并且这条边的终点是x号节点  举个例子,下图中左边是trie树,右边是二维数组trie中非0的值
mathor
2018/07/24
6600
TRIE(2)
相关推荐
剑指Offer——Trie树(字典树)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验