【问题标题】:Ternary tree vs trie with map as transition table for Aho-Corasick FSA三叉树与树与地图作为 Aho-Corasick FSA 的转换表
【发布时间】:2013-04-04 18:58:56
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

    三叉搜索树 (TST) 和在每个节点上使用二叉搜索树实现的 Trie 之间没有真正的区别。实际上,您可以将后者视为前者的(低效)实现; TST 的优点是易于优化,空间开销合理。

    经典的 Trie 在决策节点上使用按符号索引的转换向量直接查找。这是O(1) 时间,但空间需求很大。尽管如此,还是有一些优化存储的方法。此外,还存在混合解决方案,其中 Trie 结构仅用于树顶部的宽决策节点;一旦候选者的数量减少到很小的程度,就可以使用快速扫描或哈希表来找到合适的候选者。

    以幼稚的方式使用(符号,状态)转换的排序向量需要O(log T)每次转换的时间,其中T是转换的总数;本质上是所有输入字符串的总大小。给定目标的总时间将为|target|*log(T)

    相比之下,TST 每次转换所需的时间不超过O(log S),其中S 是字母表的大小;这比T 小得多。而且,整个目标字符串的总查找次数受限于输入字符串的数量,所以整个查找的总和比|target|*log(S)要少。

    【讨论】:

    • 你为什么建议 vector 的大小为 O(T)?我看不出这里与使用二叉搜索树有什么区别。如果自动机是确定性的,那么每个状态的转换不能超过字母表的大小。
    • @lizarisk:也许我误解了你的建议。您不是建议为整棵树使用一个数组吗?或者你是在为每个州建议一个向量?如果是后者,它在道德上等同于二叉搜索树,所以我真的不明白这个问题的重点。 (例如,在实践中,我的 TST 实现确实使用了向量而不是单个节点,但我认为这是一个实现细节。)
    • 我建议每个州都有一个向量。就搜索复杂度而言,它相当于二叉搜索树,但我认为由于内存中的密集表示,它更有效。
    • 我想知道的是转换表的排序向量是否比三叉树更有效。也许没有实际测试很难说,但是我听说三叉树被广泛使用,只要我们不需要动态结构,向量方法对我来说似乎更有效,所以问题是为什么要使用 TST ?
    • 如果您的字母表有 26 个字母,假设转换表的填充适中,向量占用的空间与三叉树大致相同。如果你的字母表是 unicode,你的向量会很大,而三叉树可能会很小。无论如何,获得正确答案的唯一方法是编写程序的两个版本,并将它们与实际数据进行比较,看看哪个版本在您的特定情况下更好。
    【解决方案2】:

    鉴于 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;
    
    }
    

    来源:

    【讨论】:

      猜你喜欢
      • 2010-10-23
      • 2023-04-03
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2015-09-24
      相关资源
      最近更新 更多