问题描述
规则如下: 它不能以字母 a 开头。 它不能以字母 b 结束。 它必须包含 b=i a=2i。 字母表是a,b。 我试过清空堆栈。但不幸的是我无法达到它。 像这样的输入例如: bbaaaa 没问题,因为对于我放置在堆栈中的每个 b 输入 2 a 和 a 输入删除堆栈。 但是当输入是这样的时候: baaabbaaa 不能遵循这些步骤。 有什么建议吗?
解决方法
我的方法是这样的:
使初始状态接受(因为空字符串满足语言标准)并且在 b 上有一个单一的转换到另一个状态。作为此转换的一部分,将两个 b 压入堆栈。如果在初始状态下看到 a,PDA 将崩溃并拒绝。
我们转换到的另一个状态对应于刚刚看到 b。因为我们的字符串不能以 b 结尾,所以这个状态不能被接受。如果我们在这里看到另一个b,我们可以循环回到这个状态,每次向堆栈中再添加两个b(如果堆栈顶部有b)或者取消两个a(如果有两个a)或替换a与 b (如果堆栈只有一个 a)。如果我们看到一个 a,我们必须进入一个新的状态,我们应该从堆栈中弹出一个 b(如果有 b)或压入另一个 a(如果 a 在顶部)。
第三个状态意味着我们最后看到了一个 a,所以如果我们在这里用完输入并且堆栈为空,我们应该接受。如果我们看到 a,我们可以留下并弹出 b(如果 b 在顶部)或推动 a(如果 a 在顶部)。如果我们看到b,我们应该返回到第二种状态并压入两个b,弹出两个a,或者弹出a并压入b,具体取决于堆栈内容。
我们的堆栈会跟踪 PDA 必须查看以清除堆栈的附加符号的数量,如下所示:
- 堆栈一次只会包含 a 或 b,而不会同时包含两者
- 如果我们已经看到 n a 和 m b 并且 n = 2m,则堆栈将为空
- 如果我们看到 n a 和 m b 并且 n > 2m,那么堆栈中将有 n - 2m a
- 如果我们已经看到 n a 和 m b 并且 n