使用三元树的FSA与作为搜索树实现的转换表的trie(例如std :: map)之间有什么区别?看起来两个读取一个符号的O(log k)复杂度和O(S)内存复杂度,其中k是字母大小,S是所有接受的输入字符串的长度之和。
如果我们不需要自动机在运行时更改,那么最好选择使用(符号,状态)转换对的排序向量以及二进制搜索吗?
答案 0 :(得分:2)
三元搜索树(TST)与在每个节点使用二叉搜索树实现的Trie之间没有真正的区别。实际上,你可以认为后者是前者的(效率低下)实施; TST的优势在于它们可以轻松优化,空间开销合理。
经典的Trie在决策节点上使用直接查找,并使用符号索引的过渡向量。这是O(1)
时间,但空间要求很大。尽管如此,还是有一些优化存储的方法。此外,存在混合解决方案,其中Trie结构仅用于树顶部的宽决策节点;一旦候选人数减少到很小,可以使用快速扫描或哈希表来找到合适的候选人。
以天真的方式使用(符号,状态)转换的有序向量,每次转换需要O(log T)
次,其中T
是转换的总数;基本上是所有输入字符串的总大小。给定目标的总时间为|target|*log(T)
。
相比之下,TST每次转换所需的时间不超过O(log S)
,其中S
是字母表的大小;这是一个比T
小得多的数字。此外,整个目标字符串的查找总数受输入字符串数量的限制,因此整个查找的总和小于|target|*log(S)
。
答案 1 :(得分:0)
鉴于Aho-Corasick如何说明,
这是我的节点:
public class AhoCorasickNode
{
// This part works as a Trie
public char literal; // c
public String stack; // abc
public AhoCorasickNode previous; // { ab }
public AhoCorasickNode[] next; // { abca }, { abcb }, { abcc }, ..
//-----------------------------
// This part is used when solving
boolean inDictionary;
public AhoCorasickNode suffix;
public AhoCorasickNode dictionarySuffix;
}
来源: