NFA表示的数据结构

时间:2010-12-31 15:33:27

标签: data-structures nfa

在我的词法分析器生成器中,我使用McNaughton和Yamada算法进行NFA构造,其中一个属性从I转换为J,在J位置用char标记。

因此,NFA的每个节点都可以简单地表示为下一个可能状态的列表。

哪种数据结构最适合存储此类数据?它必须提供所有可能状态的快速查找并使用更少的空间,但插入时间并不那么重要。

1 个答案:

答案 0 :(得分:2)

我的理解是你要编码一个图形,其中节点是状态,边是转换,每个边都用字符标记。这是对的吗?

枯燥但实际的答案是为每个状态设置一个对象,并在该对象的某个小结构中编码转换。

最简单的一个是数组,由字符代码索引:它尽可能快,但自然空间效率不高。通过使用一种偏移的截断数组,可以使其更节省空间:仅存储包含转换的数组部分,以及该部分的开始和结束索引。查找其中的字符时,请检查其代码是否在边界内;如果不是,则将其视为空边(或返回起始状态或其他边缘),如果是,则在索引处获取元素(字符代码 - 开始)。这有意义吗?

更复杂的选项是一个小哈希表,它会更紧凑但稍慢。我建议关闭散列,因为碰撞列表会占用太多内存;线性探测应该足够了。您可以考虑使用完美散列(查找),这需要花费大量时间来生成表格,然后进行无冲突查找。但是,生成过程非常复杂。

一种聪明的方法是同时使用数组和哈希表,并根据边数选择一个或另一个:如果压缩数组超过,比如第三个完整,请使用它,但如果没有,使用哈希表。

现在,你可以做的更激进的事情就是使用数组,但重叠它们 - 如果它们稀疏,它们会有很多洞,如果你很聪明,你可以安排它们这样每个数组中的条目与其他数组中的孔对齐。这将为您提供快速查找,同时还具有出色的内存效率。您需要一些方案来区分查找何时找到某个东西,当它找到一个空槽并且其他状态已经过渡时,但我确信您可以想到某些东西。