`

字典树(trie tree)

阅读更多
     今天AC了两题trie tree的题目,感觉trie的性质真的是相当的好,而且实现比较简单。它使在字符串集合中查找某个字符串的操作的复杂度降到最大只需O(n),其中n为字符串的长度。trie是典型的将时间置换为空间的算法,好在ACM中一般对空间的要求很宽松。
     trie的原理是利用字符串集合中字符串的公共前缀来降低时间开销以达到提高效率的目的。
它具有以下性质:1,根结点不包含任何字符信息;2,如果字符的种数为n,则每个结点的出度为n(这样必然会导致浪费很多空间,这也是trie的缺点,我还没有想到好点的办法避免);3,查找,插入复杂度为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级数。(谁有好办法降低空间开销,请告诉我)
 
------------------------------------------------
题目和我上面举的例子差不多,是说给定一个字符串集合,然后每次询问时给出一个字符串,问以该字符串为前缀的字符串在集合中有多少个。先给个用MAP版本的,限时2000MS的题目,用MAP,1750MS,险过。
my code1:
 

#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版本的。

my code2:

#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';
        if(location->next[branch]) location->next[branch]->count++;//如果该字符存在,串数量加1
        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;
}

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

分享到:
评论

相关推荐

    Java实现字典树TrieTree

    总的来说,Java实现的字典树TrieTree是一个强大的工具,尤其适用于处理大量字符串数据,如四六级高频词汇的存储和查询。通过理解和运用这种数据结构,我们可以提高算法效率,优化应用程序的性能。

    11 TrieTree.rar

    在众多的数据结构中,TrieTree(又称前缀树或字典树)是一种高效且具有广泛应用场景的结构。本篇将深入探讨TrieTree的基本概念、构造方法以及在实际中的应用。 一、TrieTree概述 TrieTree是一种基于字符串的查找...

    LeetCode-Python-820. 单词的压缩编码(字典树 Trie Tree)

    给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A。 例如,如果这个列表是 [“time”, “me”, “bell”],我们就可以将其表示为 S = “time#bell#” 和 indexes = [0, 2, 5]。...

    【ASP.NET编程知识】TrieTree服务-组件构成及其作用介绍.docx

    TrieTree,又称字典树或前缀树,它允许快速查找具有相同前缀的字符串,常用于搜索引擎和自动补全功能。下面将详细介绍TrieTree服务的组件构成及其作用。 1. **Dictionary组件**: Dictionary组件是TrieTree服务的...

    HASH(Trie)-.rar_HashTree.h_TRIE_hash树_trie树_字典树

    **哈希 Trie 树(HashTrie)与字典树(Trie树)详解** 哈希 Trie 树,也称为 HashTrie 或者是哈希化的 Trie 树,是一种结合了哈希表和 Trie 数据结构特点的数据结构。它在 Trie 树的基础上引入了哈希函数,提高了...

    基于知识图谱和trietree的垃圾分类

    TrieTree(字典树),又称为前缀树,是一种用于快速查找的数据结构。在垃圾分类应用中,TrieTree可以用来高效地存储和检索垃圾名称,实现对垃圾名称的快速匹配。例如,用户输入“废旧电池”,系统会通过TrieTree迅速...

    PHP-TrieTree-master.zip

    【PHP-TrieTree-master.zip】是一个包含PHP实现的字典树(Trie Tree)数据结构的资源包。这个项目由AbelZhou在GitHub上开源,提供了完整的代码库供开发者学习和使用。字典树是一种高效的数据结构,常用于字符串搜索...

    详解字典树Trie结构及其Python代码实现

    总结来说,字典树Trie是一种高效的数据结构,特别适合处理大量字符串并需要快速查找公共前缀的情况。虽然它的空间需求较高,但在时间和性能优化方面,Trie在某些应用场景下优于传统的哈希表。通过Python的嵌套字典,...

    11 TrieTree.zip

    本资料包"11 TrieTree.zip"专注于一个特定的数据结构——Trie(也称为前缀树或字典树),这是在文本处理、搜索引擎优化以及许多其他领域中广泛应用的一种高效工具。TrieTree是由著名计算机科学家严蔚敏教授在《数据...

    C# TrieTree介绍及实现方法

    C#中的TrieTree,又称字典树,是一种高效的数据结构,尤其在自然语言处理(NLP)和文本搜索领域有着广泛的应用。它的主要功能是存储字符串集合,并允许快速查找和匹配这些字符串。TrieTree的基本思想是通过将字符串...

    POJ2513-Colored Sticks【TrieTree+MergeSet+EulerPath】

    【标题】"POJ2513-Colored Sticks【TrieTree+MergeSet+EulerPath】"涉及的是一道编程竞赛题目,主要考察参赛者的数据结构与算法应用能力,特别是Trie树(字典树)、并查集(MergeSet)以及欧拉路径(Euler Path)这...

    字典树php实现

    `TrieTree` 类是字典树的核心类,负责构建整个字典树结构,并提供插入、搜索等基本操作。 - **属性** - `$root`: 字典树的根节点。 - **构造函数** - 初始化 `$root` 为一个新的 `TrieNode` 实例,设置其 `$flag...

    POJ2525-Text Formalization【TrieTree】

    《POJ2525-Text Formalization:深入解析TrieTree》 在计算机科学的世界里,算法和数据结构是解决问题的关键。今天我们要探讨的是一个名为"POJ2525-Text Formalization"的问题,它涉及到一种高效的数据结构——Trie...

    字典树的模版(模版)

    在计算机科学领域,字典树(Trie Tree),也被称为前缀树或关键字树,是一种用于存储字符串集合的高效数据结构。与传统的搜索树相比,字典树能够通过共享公共前缀来节省空间,特别适用于处理大量词汇的查找、插入和...

    Go-trie-单词查找树实现Go实现

    Trie,又称为前缀树或字典树,是一种用于存储动态集合或关联数组的树形数据结构。它的主要特点是通过键的前缀来组织节点,从而快速进行前缀查询和模糊搜索。在Go语言中实现Trie,可以有效地支持字符串集合的增删查改...

    Trie树(字典树)的介绍及Java实现

    Trie树,也被称为字典树或前缀树,是一种数据结构,主要用于高效地存储和检索字符串集合中的数据。在Trie树中,每个节点代表一个字符串的前缀,从根节点到某个节点的路径上的字符序列构成了该节点对应的字符串。这种...

    字典树_英汉词典

    ### 字典树(Trie Tree)相关知识点 #### 一、什么是字典树? 字典树,也称为前缀树或Trie树,是一种用于存储字符串的高效数据结构。它利用了字符串之间的公共前缀来减少存储空间的需求,并且能够快速进行插入、...

    TrieTree服务-组件构成及其作用介绍

    TrieTree服务是一种用于语言处理的技术,它通过一种特别的数据结构——前缀树(或称为字典树)来高效地存储和检索字符串数据。TrieTree服务的组成可以分解为多个关键组件,每个组件都有其特定的作用。本文将详细介绍...

    java8源码-BlogDemo:我的csdn博客中使用的代码,主要是算法

    trietree 20160624 KMP算法 KMP 20160701 排序算法,插入排序算法、合并排序算法 sort 20160702 MongoDB应用示例 mongoDBDemo 20160703 Redis的java应用示例 JedisDemo 20160704 使用itext读写pdf示例 pdf 20160705 ...

Global site tag (gtag.js) - Google Analytics