Trie implementation

  在学习 Aho - Corasick Automation Algorithm 之前,先学习一下,Trie 的实现过程:

  The name trie comes from its use for retrieval (检索) , 通常读“/ tri /" ;

  Trie is a special kind of tree ;

  What  is  trie  ?

  给你七八百个单词,然后随意给你一个单词,问一下这个单词是不是在这七八百个单词之中,if we stroe these words in liner array , it will be very unefficient (需要很大的内存,同时查找也需要很长时间). The model of trie more efficient ;

  reading more on Wikipedia page .

  通过下面的图,直观的介绍一下,数据在 Trie 中的存储方式:

  

A trie for key "A", "to", "tea", "ted", "ten", "i", "in", and "inn".

这样很 easy 避免了几个单词中具有重复部分占用内存空间的情况;

we store only the individual characters of the string key in the nodes

each node can have multiple children , 从 a 到 z (特殊考虑一下,全部为小写,不包含数字字符)同样造成了空间大量的浪费;不过没关系,我们可以找到某种方法,把那些不存在字符的结点给 detele 掉 即可 ;

在 Trie 中可以实现插入、删除、查找等功能,实现的功能不同,结点中的数据成员有所不同;

HDU中有一道题是关于 Trie 的运用 ,大致描述一下题意:

  输入N组电话号码,在输入的过程中,如果出现包含的情况,最后结果就输出NO,否则输出YES ;

  第一次用 Hash table 做的,果然不出所料,以超时而放弃,然后换为Trie来解答,结果没有delete掉不用的内存空间,结果内存超了,最后用了个递归,把不用的内存全部给delete掉,OK了!

下面给出这道题的代码,其中也有许多细节需要注意的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
using namespace std ;
 
struct Node {
    bool flag ;
    Node *next[11] ;
} ;
 
Node* new_Node()    {
    Node *root = new Node ;
    root->flag = false ;
    memset(root->next,NULL,sizeof(root->next));
    return root ;
}
bool tag ;
 
void deletee( Node *r ) {
    for(int i = 0 ; i < 10 ; i++)    {
        if(r->next[i] != NULL)
            deletee(r->next[i]) ;
        delete(r->next[i]) ;
    }
}
 
void Construct_trie(Node *point , char *s)  {
    int len = strlen(s) ;
    for(int i = 0 ; i < len ; i++)   {
        if(point->flag || (point ->next[s[i]-'0'] != NULL && i == len - 1))
            tag = false ;
        if(point->next[s[i]-'0'] == NULL)
            point->next[s[i]-'0'] = new_Node() ;
        point = point->next[s[i]-'0'] ;
    }
    point->flag = true ;
}
 
 
int main()  {
    int m ;
    scanf("%d", &m) ;
    while(m--)  {
    int n ;
    scanf("%d",&n) ;
    Node *root = new_Node() ;
    tag = true ;
    while(n--)  {
        char s[10005] ;
        scanf("%s",&s) ;
        Construct_trie(root,s);
    }
    if(tag)
        printf("YES\n") ;
    else
        printf("NO\n") ;
    deletee(root) ;
    }
    return 0 ;
}

 

 

posted @   scott_ding  阅读(269)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示