字典树的建立和基本查找

字典树的建立和基本查找

一.字典树的定义

字典树又叫做前缀树,任意一个或多个字符串可以构建一棵字典树用于存储多个串的公共前缀

二.构建字典树的两种方法

(1)字典树的链表构建及查找

在用链表构造的字典树中每一个节点有着一个数据域来存放该点代表的字符和26个指针分别指向a(A)~z(Z)26个可能出现的子字符,在寻找某个字符串是否出现时,从根节点出发不断向下查找配对,如果到了最后一个字符都存在则表示该前缀存在

(2)字典树的二维数组构建及查找

用二维数组tree[i][j]来标识一颗字典树,其中i为父节点,j为子节点,程序开始时父节点为root节点。tree[i][j]表示节点i第j个儿子的编号【这里我们规定root的编号为0】

1) 字典树的二维数组构建

2)字典树的二维数组查找

三.代码模板

(1) 字典树的链表模板

const int SIZE=10;
struct Trie
{
int count;//前缀出现的次数
struct Trie *next[SIZE];//孩子节点的数目
bool isEnd; //判断到这个位置是否是一个单词
string name;
Trie()//构造函数
{
count=0;
memset(next,0,sizeof(next));
isEnd=false;
}
};
struct Trie *root=new Trie;//建立根节点
void Insert(string s)
{
int len=s.length();
int pos;
struct Trie *u=root;
for(int i=0;inext[pos]==NULL)//数字在边上,或者说是以位置的方式体现,不需要存储
u->next[pos]=new Trie;
u=u->next[pos];
u->count++;
}
u->isEnd=true;//表明为一个单词的节点
u->name=s;//同时存储单词
}
int Search(string s)
{
struct Trie *u=root;
int len=s.length();
for(int i=0;inext[pos]==NULL)
return 0;
else
u=u->next[pos];
}
return u->count;
}

 

(2) 字典树的二维数组模板

const int maxn =2e6+5;//如果是64MB可以开到2e6+5,尽量开大
int tree[maxn][30];//tree[i][j]表示节点i的第j个儿子的节点编号
bool flagg[maxn];//表示以该节点结尾是一个单词
int tot;//总节点数
void insert_(char *str)
{
int len=strlen(str);
int root=0;
for(int i=0;i<len;i++)
{
int id=str[i]-‘0‘;
if(!tree[root][id]) tree[root][id]=++tot;
root=tree[root][id];
}
flagg[root]=true;
}
bool find_(char *str)//查询操作,按具体要求改动
{
int len=strlen(str);
int root=0;
for(int i=0;i<len;i++)
{
int id=str[i]-‘0‘;
if(!tree[root][id]) return false;
root=tree[root][id];
}
return true;
}
void init()//最后清空,节省时间
{
for(int i=0;i<=tot;i++)
{
flagg[i]=false;
for(int j=0;j<10;j++)
tree[i][j]=0;
}
tot=0;
}

 

原文地址:https://www.cnblogs.com/PokimonMaster/p/12188791.html

时间: 2024-10-10 20:36:37

字典树的建立和基本查找的相关文章

hiho #1014 : Trie树 (字典树的建立和查找)

#1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?" 身经百战的小Ho答道:"怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有

剑指Offer——Trie树(字典树)

剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.可见,优

HDU 1075 map or 字典树

What Are You Talking About Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/204800 K (Java/Others)Total Submission(s): 12773    Accepted Submission(s): 4069 Problem Description Ignatius is so lucky that he met a Martian yesterday. But

字典树模板+HDU 1671 ( Phone List )(字典树)

字典树指针模板(数组模板暂时还没写): 1 #include<cstdio> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int MAX=26; 6 const int maxn=1e4+100; 7 int N; 8 9 struct Trie 10 { 11 Trie *next[MAX]; 12 int v;///v要灵活使用,具体情况具体分析 13 }; 14

C++实现字典树数据结构_LeetCode820_字典的压缩编码

用C++实现字典树数据结构的例子: 例题: 单词的压缩编码 给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A. 例如,如果这个列表是 ["time", "me", "bell"],我们就可以将其表示为 S = "time#bell#" 和 indexes = [0, 2, 5]. 对于每一个索引,我们可以通过从字符串 S 中索引的位置开始读取字符串,直到 "#" 结束,来恢复我们

uva 11732 - strcmp() Anyone?(字典树)

题目链接:uva 11732 - strcmp() Anyone? 题目大意:给定n个串,然后两两之间比较,问说总共要比较多少次. 解题思路:字典树,建立出字典树,然后根据字典树的性质在节点记录有多少个字符串包含该节点.因为节点的个数比较多,所以用左孩子右兄弟的方法建立字典树. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long

字典树用于单词联想

最近要做一个单词联想的功能,经过调研选择使用字典树,节省空间,查找快. 贴上代码 class Trie(object): def __init__(self): self.path = {} self.value = None self.valid = False def __setitem__(self, key, val): head = key[0] if head in self.path: node = self.path[head] else: node = Trie() self.

hdu杭电1671 / poj3630 字典树

传送门 题意:输入n串数字 找出是否有前缀相同的串 如果存在 输出NO否则输出YES 思路:用字典树解决 标记字典树总串的结尾 查找出一个串内部是否有被标记的节点 如果有那么说明存在前缀相同的串 在插入字典树的时候判断是否存在 AC代码: 1 #include "iostream" 2 #include "stdio.h" 3 #include "string.h" 4 using namespace std; 5 6 using namespa

Hat’s Words(字典树的运用)

个人心得:通过这道题,对于树的运用又加深了一点,字典树有着他独特的特点,那个指针的一直转换着实让我好生想半天, 不得不佩服这些发明算法人的大脑. 这题的解决方法还是从网上找到的,还好算法是自己实现得,没错!组合体只要进行分割再暴力搜索就好了, 步骤就是根据得到的字符串建立字典树,然后一一找寻时,一次拆开,只要俩边都满足在字典树里面找的到就是我们所要找的了. 关于字典树的建立的话,因为他是不知道子树的,所以只要判断出来不存在子树就malloc一个就好了, 注意指针的指向和递归的奥妙,很多更新都是在