Trie树的各种实现

前缀匹配在自然语言处理中常见的需求。 假设有一个词典和一个句子,找出句子开始位置处匹配的词典中的单词。

Hash标记法

使用一个HashMap,放入词典中词的同时放入前缀词。例如当插入词典中的hello这个词时,同时插入hello的前缀词。

map["hello"] = 1
map["hell"] = 0
map["hel"] = 0
map["he"] = 0
map["h"] = 0

这样查找遇到0的时候继续追加字符进行查找。

传统的Trie树

使用utf8编码,每一字节有256中可能的后缀。

TrieNode {
	char ch;
	TrieNode children[256];
}

这种方式在汉字处理有很多空间浪费。

字节分割法

传统的Tire树只能存储英文。如果是汉字,可以按字节来分割。例如utf8编码有3个字节,我们没半个字节分一个数出来,那么一个汉字专为6个字母。

Hash基础的Trie

孩子结点放入一个哈希表中。

TrieNode {
	char ch;
	Map<char,TrieNode*> children;
}

缺点是序列化不太方便,占用内存大。

二分数组基础的Trie

孩子结点排序,然后进行二分查找。

TrieNode {
	char ch;
	Array<TrieNode> children;
}

二分查找可能没有其他方式快。插入时也要移动内存。

Double Array Trie

整个trie被存储为base和check两个数组。相当于将子结点数组压缩到一个单个数组中。

详见

DoubleArrayTrie容易序列化,但构建速度较慢。

Radix Trie

大概意思是将只有一个子结点和父节点合并,来压缩trie树。

Aho-Corasick

这是一个自动状态机算法,用在多模式匹配。类似与KMP算法的思路,在匹配失败的情况下转移到远的结点。t

转载于:https://my.oschina.net/chunquedong/blog/1629850

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值