下推自动机详讲 包含Java实现 Pushdown Automata (PDA)

下推自动机也可以叫下推有限自动机或者下推状态机,是一种实现无上下文语法的方法,类似于我们为常规语法所设计的有限状态机, 它是有限自动机的增强版。和有限状态机相比,它多了一个叫栈的数据结构。所以相比于有限状态机,它更加强大,能够记忆更多的内容。

实现源码 (Java) Source Code of Pushdown Automata

可以参考本人另一篇文章, 同样有Java实现源码:确定有限自动状态机和非确定有限自动状态机详解(Nondeterministic finite automata)

在这篇博文中,我们打算使用和有限状态机作相比较的方法来讲解。下图所示的是一个有限状态机,其中,状态根据输入字符来确定状态的转换。比如如果当前状态为A,输入为a,那么下一状态为B。
这里写图片描述

而对于下推有限状态机,决定状态A变化的不仅仅是输入a,同时还有b和c。其中,对于b,表示弹出当前栈顶元素b,如果当前栈顶元素不是b,则不满足状态转换条件,其中符号b可能为空,表示不需要弹出栈中的元素。对于符号c,表示将要压入栈中的元素,其中c可能为空,表示不需要压入任何元素到栈中。所谓的栈,是一种数据结构,特点是其中的元素满足先进后出的原则,本文假设读者已经了解它。
这里写图片描述

它们之间是存在包含关系的,下图来自wikimedia
下推自动机详讲 包含Java实现 Pushdown Automata (PDA)_第1张图片

上面便是有限状态机和下推状态机主要的区别。从直观的角度来看,下推状态机多了一个栈的数据结构,相应地也多了两个变量b和c,分别指明在状态转换的时候应该向该数据结构中弹出和压入哪些元素。同样的格式,下面我们来看一个更加复杂的下推状态机,如下图所示。图片中和E很像的符号表示空,也就是表示不输入任何数据,或者不进行压栈或者弹栈操作。

下推自动机详讲 包含Java实现 Pushdown Automata (PDA)_第2张图片

我们来分析一下上图中状态转换的过程。如果当前状态为q1,输入为空,也就是没有输入,当状态从q1到q2的时候,不需弹栈操作,向栈中压入元素z0。其中z0只是单纯地表示栈中最底下的元素,作为开始或者结束符,没有其他特殊的含义。接下来,如果输入0,从状态q2转换为q2(自身),不弹栈,将0压入栈中。接下来,如果输入1,弹出栈顶元素0(如果此时栈顶元素不是0,则不能执行该状态转换),不需压栈,状态从q2转为q3。以此类推,直到检测完所有的输入字符,并且最后的结束状态为q4,这样的话,表示所输入的字符串满足该下推状态机,否则不满足。上面图片所示的下推状态机满足所有以格式{01, 0011, 000111…}的输入字符串。

下图所示的下推状态机能够满足所有以格式{abba, aaaa, abaaba …}的输入字符串。需要注意的是下图中状态q2向q3转换时的条件:其没有输入,不用弹栈和压栈操作。在编程实现中,我们需要考虑到这样的状态转移条件。具体来讲,下图中我们将要检查的字符串为abba,而实际上我们需要检测的字符串为 a ϵ b ϵ b ϵ a,其中ϵ表示空。
下推自动机详讲 包含Java实现 Pushdown Automata (PDA)_第3张图片

下面我们一步一步演示在检测字符串abba(实际上是a ϵ b ϵ b ϵ a,其中ϵ表示空)的时候该状态机的状态转移情况以及栈的元素变化。使用index表示当前所检查到的字符的下标位置,初始为0. 在阅读下面的步骤的时候,最好对比着看上面和下面两张图片。下面的图片是由上面图片的结构和输入的字符串决定的。
下推自动机详讲 包含Java实现 Pushdown Automata (PDA)_第4张图片

  • 没有输入,没有弹栈,将z0压栈,状态从q1到q2。

  • index=0,输入a,没有弹栈,将a压栈,状态从q2到q2.

  • 接下来与两个分支,需要分别检测输入为 ϵ 和b的情况:

  • (1)当输入为空时,index=0不变, 没输入,无弹栈和压栈,状态从q2到q3. 因为这个分支最终不满足状态机,所以我们不深入这个分支。

  • (2)当输入为b时,index=1,输入为b,无弹栈,将b压栈,状态从q2到q2. 现在栈中的元素为[b,a,z0], 。接下来同样检查输入ϵ 和b。当输入为ϵ的时候,index=1不变,无弹栈和压栈,状态从q2到q3;如果输入为b的时候,同样道理,index=2。此时的状态在上图中对应最下面两个栈。

  • 执行到这里,我们转到下面这个图片。

  • 现在我们到了下图所示红框的位置。看红框中左边的栈,此时状态为q3. 此时index=2,也就是输入为b,将栈顶元素b出栈,无压栈,状态从q3转到q3.

  • 接下来,index=3,也就是输入为a,将栈顶元素a弹出,无压栈,状态从q3转到q3.

  • 输入为ϵ,将z0出栈,无压栈,状态从q3转到q4,此时栈为空。此时满足两个条件:(1)遍历完了所输入的字符串;(2) 此时恰好处在结尾状态。所以,该字符串满足该自动机。
    下推自动机详讲 包含Java实现 Pushdown Automata (PDA)_第5张图片

实现的程序针对上面所给的例子进行了测试

谢谢

你可能感兴趣的:(java,stream,process)