惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
V2EX - 技术
V2EX - 技术
The Last Watchdog
The Last Watchdog
宝玉的分享
宝玉的分享
T
Tenable Blog
WordPress大学
WordPress大学
K
Kaspersky official blog
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Hacker News - Newest:
Hacker News - Newest: "LLM"
P
Palo Alto Networks Blog
Help Net Security
Help Net Security
V
Vulnerabilities – Threatpost
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
Forbes - Security
Forbes - Security
Microsoft Azure Blog
Microsoft Azure Blog
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
H
Hacker News: Front Page
W
WeLiveSecurity
博客园 - 【当耐特】
G
Google Developers Blog
Martin Fowler
Martin Fowler
TaoSecurity Blog
TaoSecurity Blog
Hacker News: Ask HN
Hacker News: Ask HN
人人都是产品经理
人人都是产品经理
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
AI
AI
N
Netflix TechBlog - Medium
C
Cisco Blogs
I
Intezer
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
G
GRAHAM CLULEY
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
小众软件
小众软件
Blog — PlanetScale
Blog — PlanetScale
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
Engineering at Meta
Engineering at Meta

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟 从Python转向Pharo https://blog.just4fun.site/post/iot/iot-open-source-projects/ Python异步编程笔记 https://blog.just4fun.site/post/iot/iot-open-source-hardware-community/ 万物积木化开发者社区 CodeLab ❤️ Blender Scratch3技术分析之云变量 API(第7篇) [译]对管道(Pipes)的偏爱 [译]提出正确的问题比得到正确答案更重要 蓝牙设备与Scratch3.0 创建你的第一个Scratch3.0 Extension Scratch3技术分析之项目内部数据(第6篇) Scratch3技术分析之社区 API(第5篇) Scratch3技术分析之User API(第4篇) Scratch3技术分析之项目主页API(第3篇) Scratch3技术分析之静态资源API(第2篇) Scratch3.0、micro:bit与Windows7 https://blog.just4fun.site/post/iot/zerynth-vs-micropython/ 核聚变、方所与半宅空间 可视化编程为何是个糟糕的主意 codelab.club周末聚会 关于codelab.club '下一件大事'是一个房间 Hungry Robot - Eat everything 编程作为一种思考方式 今日简史 史蒂夫·乔布斯传 罗素自选文集 https://blog.just4fun.site/post/edx/tianjin-scratch-ai/ https://blog.just4fun.site/post/edx/richie-cms-openedx/ 徒步武功山 WebUSB与micro:bit 积木化编程与3D场景 夜宿武功山顶 scratch3-adapter接入优必选Alpha系列机器人 https://blog.just4fun.site/post/edx/video-migration-note/ scratch3-adapter重构笔记 https://blog.just4fun.site/post/edx/edx-community-members/ 两种硬件编程风格的比较 使用micro:bit自制PPT翻页笔 柏拉图对话集 scratch3.0 + micro:bit 七月电影放映计划 非营利组织的管理 Screenly--用树莓派让任何屏幕变为可编程的数字标牌 以最佳实践开始你的Django项目 micro:bit与事件驱动 为Scratch3.0设计的插件系统(上篇) OCR应用一例 近两年读过的一些好书 blockly开发之使用python驱动浏览器中的turtle(2) 牛顿新传 文学理论入门 逻辑的引擎 人生的意义 blockly开发之生成并运行js代码(1) blockly开发之hello world(0) micro:bit使用笔记 神器之Termux https://blog.just4fun.site/post/iot/micropython-notes/ Cozmo what is this Scratch的前世今生 下段旅程 我行在远方 爆裂 途中杂记 https://blog.just4fun.site/post/edx/open-edx-startup/ cozmo系列之入门 - 有性格且可编程的机器人 PaperWeekly开发笔记 创业二三事
算法笔记之trie树
2016-08-13 · via 夜行人

文章目录

一个保存了8个键的trie结构

图片来自维基百科

介绍

trie,又称前缀树/字典树/单词查找树,是一种有序树

Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的

上图图示说明

图示中,键标注在节点中,值标注在节点之下。每一个完整的英文单词对应一个特定的整数。Trie可以看作是一个确定有限状态自动机。键不需要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示trie的原理

读音

trie的发明者Edward Fredkin把它读作英语发音:“tree”。但是,其他作者把它读作英语发音:“try”。

基本特性

  • 根结点不包含字符,除根节点意外每个结点只包含一个字符
  • 从根结点到某个结点,经过的字符连接起来,为该结点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

基本操作

基本操作有:查找、插入和删除,当然删除操作比较少见

应用

典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串)

trie树常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能

在我们做NLP中命名实体识别(NER),采用字典法时,可能会用到trie-tree作为快速搜索算法

可视化

C语言实现

 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
62
63
64
65
66
67
68
#define MAX 26//字符集大小
typedef struct TrieNode
{
    int nCount;//记录该字符出现次数
    struct TrieNode* next[MAX];
}TrieNode;
 
TrieNode Memory[1000000];
int allocp=0;
 
/*初始化*/
void InitTrieRoot(TrieNode* *pRoot)
{
    *pRoot=NULL;
}
 
/*创建新结点*/
TrieNode* CreateTrieNode()
{
    int i;
    TrieNode *p;
    p=&Memory[allocp++];
    p->nCount=1;
    for(i=0;i<MAX;i++)
    {
        p->next[i]=NULL;
    }
    return p;
}
 
/*插入*/
void InsertTrie(TrieNode* *pRoot,char *s)
{
    inti,k;
    TrieNode*p;
    if(!(p=*pRoot))
    {
        p=*pRoot=CreateTrieNode();
    }
    i=0;
    while(s[i])
    {
        k=s[i++]-'a';//确定branch
        if(!p->next[k])
            p->next[k]=CreateTrieNode();
                p->next[k]->nCount++;
        p=p->next[k];
    }
}
 
//查找
int SearchTrie(TrieNode* *pRoot,char *s)
{
    TrieNode *p;
    int i,k;
    if(!(p=*pRoot))
    {
        return0;
    }
    i=0;
    while(s[i])
    {
        k=s[i++]-'a';
        if(p->next[k]==NULL) return 0;
        p=p->next[k];
    }
    return p->nCount;
}

python描述

  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
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
""" Tries in python
Methods -  insert_key(k, v)
           has_key(k)
           retrie_val(k)
           start_with_prefix(prefix)
"""


def _get_child_branches(trie):
    """
    Helper method for getting branches
    """
    return trie[1:]


def _get_child_branch(trie, c):
    """
    Get branch matching the character
    """
    for branch in _get_child_branches(trie):
        if branch[0] == c:
            return branch

    return None


def _retrive_branch(k, trie):
    """
    Get branch matching the key word
    """
    if not k:
        return None

    for c in k:
        child_branch = _get_child_branch(trie, c)
        if not child_branch:
            return None
        trie = child_branch

    return trie


def _is_trie_bucket(bucket):
    if len(bucket) != 2:
        return False

    return type(bucket[1]) is tuple


def _get_bucket_key(bucket):
    if not _is_trie_bucket(bucket):
        return None

    return bucket[1][0]


def has_key(k, trie):
    """
    Check if trie contain the key word
    """
    return _retrive_branch(k, trie) is not None


def retrie_val(k, trie):
    key_tuple = _retrive_branch(k, trie)
    if not key_tuple:
        return None

    return key_tuple[1]


def insert_key(key, v, trie):
    """
    Insert a (key, value) pair into trie
    """
    if not key or has_key(key, trie):
        return

    for char in key:
        branch = _get_child_branch(trie, char)
        if not branch:
            new_branch = [char]
            trie.append(new_branch)
            trie = new_branch
        else:
            trie = branch
    trie.append((key, v))


def start_with_prefix(prefix, trie):
    """
    Find words start with prefix
    """
    branch = _retrive_branch(prefix, trie)
    if not branch:
        return []

    prefix_list = []
    q = branch[1:]
    while q:
        curr_branch = q.pop(0)
        if _is_trie_bucket(curr_branch):
            prefix_list.append(_get_bucket_key(curr_branch))
        else:
            q.extend(curr_branch[1:])

    return prefix_list
使用
 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
trie = [[]]
states = """
            Alabama
            Alaska
            Arizona
            Arkansas
            California
            Colorado
            Connecticu
            Hawaii
            Idaho
            Illinois
            Indiana
            Maine
            Maryland
            Massachusetts
            Michigan
            Minnesota
            Mississippi
            Missouri
            Montana
"""
states_list = [w.strip().lower() for w in states.splitlines() if w]
for state in states_list:
    insert_key(state, True, trie)
print start_with_prefix("new", trie)

参考

文章作者 种瓜

上次更新 2016-08-13