构造下推自动机
Construct pushdown automata
我在今天的讲座中学习了下推自动机,但是因为没看懂所以发了个问题。我不知道为什么要在这里使用堆栈。
(a) {a^n b^m a^n ┤| m,n∈ N,m>0,n>0}
(b) {a^i b^j c^k ┤| i,j,k∈ N,i≥0,k≥0,i+k=j}
谁能用这个例子构造下推自动机以及如何使用栈?
我们需要 (a) 的堆栈,因为我们必须记住我们在前面看到了多少个 a,这样我们才能确保我们在后面有相同的数字。为此,PDA 可以将 a 压入堆栈,直到它看到第一个 b;然后,它可以读取 b;然后,它可以读取剩余的 a,从堆栈中一对一地弹出,直到 运行s 没有输入。如果 PDA 在正面和背面看到相同数量的 a,则堆栈最后应该为空; PDA 可以识别这是否是真的,如果是,则接受,否则拒绝。
状态 q0:在 a 上,将 a 压入堆栈并转到状态 q0;在 b 上,转到状态 q1。
状态 q1:在 a 上,从堆栈中弹出一个 a 并转到状态 q2;在 b 上,不理会堆栈并转到状态 q1
状态 q2:在 a 上,从堆栈中弹出一个 a 并转到状态 q2;在 b 上,崩溃并拒绝输入
接受条件:状态q2,输入耗尽且栈为空
对于数字 2,我们可以使用堆栈来保持我们目前看到的非 b 与 b 余额的 运行ning 计数。我们开始读取 a 并压入堆栈;当我们开始读取 b 时,我们将 a 从堆栈中弹出,直到 运行 出栈,然后我们开始压入 b。一旦我们开始读取 c,我们就从堆栈中弹出 b,直到堆栈为空,然后开始压入 c。如果堆栈为空(意味着我们看到的非 b 的数量与我们看到的 b 的数量相同),我们接受输入,否则拒绝。
状态 q0:在 a 上,将 a 压入堆栈,留在 q0 中;在 b 上,弹出 a(如果有)或压入 b(如果堆栈为空),然后转到状态 q1。在 c 上,崩溃并拒绝
状态 q1:在 a 上,崩溃并拒绝;在 b 上,弹出 a(如果有)或压入 b(如果堆栈为空)并留在 q1 中;在 c 上,弹出 b(如果有的话)或压入 c,然后转到状态 q2。
陈述 q2:在 a 或 b 上,崩溃并拒绝;在 c 上,pop b(如果有的话)或 push c,并留在 q2.
接受条件:在状态q2,输入耗尽且堆栈为空。
我在今天的讲座中学习了下推自动机,但是因为没看懂所以发了个问题。我不知道为什么要在这里使用堆栈。
(a) {a^n b^m a^n ┤| m,n∈ N,m>0,n>0}
(b) {a^i b^j c^k ┤| i,j,k∈ N,i≥0,k≥0,i+k=j}
谁能用这个例子构造下推自动机以及如何使用栈?
我们需要 (a) 的堆栈,因为我们必须记住我们在前面看到了多少个 a,这样我们才能确保我们在后面有相同的数字。为此,PDA 可以将 a 压入堆栈,直到它看到第一个 b;然后,它可以读取 b;然后,它可以读取剩余的 a,从堆栈中一对一地弹出,直到 运行s 没有输入。如果 PDA 在正面和背面看到相同数量的 a,则堆栈最后应该为空; PDA 可以识别这是否是真的,如果是,则接受,否则拒绝。
状态 q0:在 a 上,将 a 压入堆栈并转到状态 q0;在 b 上,转到状态 q1。 状态 q1:在 a 上,从堆栈中弹出一个 a 并转到状态 q2;在 b 上,不理会堆栈并转到状态 q1 状态 q2:在 a 上,从堆栈中弹出一个 a 并转到状态 q2;在 b 上,崩溃并拒绝输入 接受条件:状态q2,输入耗尽且栈为空
对于数字 2,我们可以使用堆栈来保持我们目前看到的非 b 与 b 余额的 运行ning 计数。我们开始读取 a 并压入堆栈;当我们开始读取 b 时,我们将 a 从堆栈中弹出,直到 运行 出栈,然后我们开始压入 b。一旦我们开始读取 c,我们就从堆栈中弹出 b,直到堆栈为空,然后开始压入 c。如果堆栈为空(意味着我们看到的非 b 的数量与我们看到的 b 的数量相同),我们接受输入,否则拒绝。
状态 q0:在 a 上,将 a 压入堆栈,留在 q0 中;在 b 上,弹出 a(如果有)或压入 b(如果堆栈为空),然后转到状态 q1。在 c 上,崩溃并拒绝
状态 q1:在 a 上,崩溃并拒绝;在 b 上,弹出 a(如果有)或压入 b(如果堆栈为空)并留在 q1 中;在 c 上,弹出 b(如果有的话)或压入 c,然后转到状态 q2。
陈述 q2:在 a 或 b 上,崩溃并拒绝;在 c 上,pop b(如果有的话)或 push c,并留在 q2.
接受条件:在状态q2,输入耗尽且堆栈为空。