在为期末考试练习的过程中,我在第222页中的J.Hopcroft,R。Motwani,J。Ullman 的 Automata Theory,Language and Computation中找到了这个问题。
PDA应该接受字符串,其中1的数字是0的数字的两倍,如果我没有误解问题,字符串可以有不同的序列0&# 39; s和1没有特定的模式或特定的顺序。
我解决这个问题的第一个方法是将问题分成两部分
但是,将问题分开似乎不会降低问题的复杂性。
应该采取什么方法解决这些问题?
答案 0 :(得分:8)
字符串是以0还是1开头并不重要,在解决这个问题时应该记住的是,我们要在堆栈中每两个1推一个1 ,如果堆栈顶部为1,同样地,如果我们遇到0作为堆栈顶部,那么我们必须仅在字符串中出现第二个时弹出它。通过使用两种状态可以很容易地实现这种动机。让状态为q0和q1。如果我们处于q0状态,那么它意味着我们没有遇到对中的前1个,而状态q1意味着我们已经遇到了对中的前1个。 PDA的各种转换如下所示。
让PDA为P({q0,q1},{0,1},{0,1,z},q0,z)
(q0,0,z)= {(q0,0z)}
(q0,1,z)= {(q1,z)}
(q0,0,0)= {(q0,00}}
(q0,1,0)= {(q1,0)}
(q0,0,1)= {(q0,ε)}
(q0,1,1)= {(q1,1)}
(q1,0,0)= {(q1,00}}
(q1,1,0)= {(q0,ε)}
(q1,0,1)= {(q1,ε)}
(q1,1,1)= {(q0,11)}
(q0,ε,z)= {(q0,ε)}
答案 1 :(得分:1)
我知道这已经有 5 年历史了,但由于尚未接受答案,我想我会分享我的答案,看看它是否对任何人有帮助(我确定它可以简化,但这是我的逻辑):< /p>
PDA 定义:P({S, M, Z, q1, F}, {0, 1}, {0, 1, $}, 下面描述的转换函数, S, {S, F})
我在下面插入了我的绘图图片,但我所做的是首先将 $ 压入堆栈以指示底部并进入状态 M。然后,如果第一个符号是零,则将零压入堆栈并进入状态z。如果是 1,则将 1 压入堆栈并进入状态 q1。在状态 z 中,如果字符串中的下一个是零,则保持状态 z 并将零添加到堆栈中。如果字符串中的下一个是 1 并且堆栈顶部有一个零,则将零从堆栈中弹出并保持状态 z。如果状态 z 中的字符串中的下一个是 1 并且堆栈为空,则移动到状态 q1 并将 1 压入堆栈。如果字符串为空并且栈顶有一个 $ 则弹出 $ 并进入状态 F。
状态 q1 除了相反之外几乎具有相同的转换。
在状态 q1 中,如果字符串中的下一个是 1,则保持状态 q1 并将一个 1 添加到堆栈中。如果字符串中的下一个是 0 并且堆栈顶部有 1,则将 1 从堆栈中弹出并保持状态 q1。如果状态 q1 中的字符串中的下一个 0 并且堆栈为空,则移动到状态 z 并将一个 0 压入堆栈。如果字符串为空并且栈顶有一个 $ 则弹出 $ 并进入状态 F。
这个逻辑绘制在下图中。
答案 2 :(得分:0)
这个想法如下:
为每个0弹出两个1或者为每个0推两个0。
为每个1弹出一个0或为每个1推一个1。
答案 3 :(得分:0)
还需要添加两个状态,其中(q1,0,z)= {(q1,0z)}和
(q1,1,z)= {(q1,1z)}。此外,为了改善答案,请保持单独的最终状态,即(q0,ε,z)= {(qf,ε)},其中,qf是最终状态。要检查有效性,可以使用以下字符串(111100、001111、110110、101110、100111、101011等)
答案 4 :(得分:0)
包含相同个零和一的语言的语法为
S -> 0S1S | 1S0S | epsilon
类似地,一种语言的语法是1的两倍为0的语言是
S -> 0S1S1S | 1S0S1S | 1S1S0S | epsilon
因此,NPDA类似于:
从q0到q1:如果您阅读epsilon
并在堆栈顶部看到z
,请按S
。
从q1到q1:如果您阅读epsilon
并在堆栈顶部看到S,则按0S1S1S
或按1S0S1S
或按1S1S0S
或弹出。如果您阅读0
并在堆栈顶部看到0
,请弹出。如果您阅读1
并在堆栈顶部看到1
,请弹出。
从q1到q2:如果您阅读epsilon
并在堆栈顶部看到z
,请弹出。
q2是最终状态。