三元树与特里与地图作为Aho-Corasick FSA的过渡表

时间:2013-04-04 18:58:56

标签: algorithm trie finite-automata ternary-search-tree aho-corasick

使用三元树的FSA与作为搜索树实现的转换表的trie(例如std :: map)之间有什么区别?看起来两个读取一个符号的O(log k)复杂度和O(S)内存复杂度,其中k是字母大小,S是所有接受的输入字符串的长度之和。

如果我们不需要自动机在运行时更改,那么最好选择使用(符号,状态)转换对的排序向量以及二进制搜索吗?

2 个答案:

答案 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如何说明,

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;

}

来源: