所以我需要创建一个TM的文字表示,找出磁带上发生最多的字符并删除其他所有字符。 TM只有一个磁带,输入看起来像这样:
#a# => #a#
#aaabbaac# => #a#
字母表是{a,b,c,d}。
我需要一些提示,因为我发现自己陷入困境。我的第一个想法是按顺序删除字符(例如,对于任何' a',尝试删除另一个' b'然后' c'然后' d& #39;如果可能的话,所以最后只会出现最多的一个,但这似乎太复杂了。
有什么想法吗?
答案 0 :(得分:2)
与任何编程任务一样,我们的想法是将其分解为可管理的部分,您知道如何在将运行程序的机器中进行编码。一旦我们制定了计划,我们就会担心如何简化计划并写下答案。
你的想法并不坏:我们可以看到第一个未擦除的符号是什么,然后向右扫描并删除每个其他非擦除符号的一个实例,直到我们得到一个空白;然后,重置并重复,直到最后没有删除最后一遍中的任何符号。然后,找到最后剩余的未擦除符号,将其复制到磁带的前面,然后将其余部分清空,直到找到右边的空白。这就是设计。
现在我们可以谈谈实施。我们需要对状态和转换进行编码,这将对上述内容产生影响。我们需要做的第一件事是读取磁带符号以确定第一个未擦除的符号是什么。我们知道TM无论如何都需要一个初始状态,所以这可能是什么。我们将致电州q0
。
如果我们在q0
并且我们看到一个空白,我们总是可以认为磁带是空的,我们可以停止接受。请注意,问题描述不包括两个边缘情况:空字符串;具有相同数量的多个符号的字符串。如果某些符号出现相同的最大次数,我们是否全部显示或者我们什么都不显示?这种推导假设我们没有显示任何内容。
如果在q0
我们在磁带上看到a
,我们需要向右扫描,最多删除一个b
,c
和d
。我们甚至可以致电州qbcd
来提醒自己我们正在寻找什么。阅读a
后,我们需要删除它;我们不一定要用空格覆盖它,因此我们可以使用特殊符号B
来表示删除。对于其他磁带可能性,我们会转换为qacd
,qabd
和qabc
。
在州qxyz
,其中x
,y
和z
代表a
,b
,{的三种组合{1}}和c
,我们希望删除d
,x
或y
中的一个,而不是其余符号。所以,如果我们看到剩下的符号,我们就会单独留下磁带并向右移动;如果我们看到符号z
,x
或y
,那么我们会转换到与要删除的两个符号相对应的状态。将有六种此类状态:z
,qab
,qac
,qad
,qbc
,qbd
。
在州qcd
,其中qxy
和x
代表y
,a
,b
和{的两种组合{1}},我们希望删除c
或d
中的一个,而不是其他两个符号。所以,如果我们看到其他符号,我们将磁带单独留下并向右移动;如果我们看到符号x
或y
,那么我们会转换到与剩余的唯一符号相对应的状态。将有四种此类状态:x
,y
,qa
,qb
。
在州qc
,其中qd
代表qx
,x
,a
和b
之一,我们希望擦除c
,但没有其他三个符号。所以,如果我们看到其他三个符号,我们将磁带单独留下并向右移动;如果我们看到符号d
,那么我们转换到指示每个符号中的一个已被删除的状态。将此状态称为x
。
如果状态为x
,qR
或qxyz
,您会发现一个真正的空白符号 - 意味着输入已用尽 - 这意味着您没有找到某些符号你想要删除。这可以;在这种情况下,我们可以转换到前一段中提到的相同状态:表示我们已完成通过并准备重复该过程的状态。
在状态qxy
中,您将磁带倒回到磁带的第一个空白区域的开头,然后转换到另一个我们将调用qx
的状态。 qR
唯一的工作就是向右扫描并找到第一个不是qF
的符号。然后,它的行为与初始状态完全相同,并重复上述过程。请注意,所有状态在读取磁带时都应忽略qF
,并将其传递给它们。我们甚至可以重复使用B
,因为输入磁带最初不会有B
个;使用这个额外功能重载q0
是安全的。
如果您到达磁带的右侧 - 所有原始输入后的空白 - 处于其中一个状态B
,则表示您删除了第四个符号q0
,但未找到在同一通道中要擦除的任何其他符号。这意味着qxyz
是最初具有最多实例的符号。当我们检测到这种特殊情况时,我们可以转换到返回磁带开头的新状态w
,w
,qa'
和qb'
,然后转换到状态{ {1}},qc'
,qd'
和qa''
向下写入输入,然后转换到qb''
以最终删除剩余的磁带,停止接受时最初在输入结束时出现空白。
这在TM中看起来像什么?
qc''
如果您宁愿将磁带头放在磁带的前面,您可以编写特殊的磁带符号,例如qd''
,qE
,state tape | new state new tape head direction
-------------------------------------------------------------
// find and erase the first symbol /////////////////////////
-------------------------------------------------------------
q0 # | halt_accept # same
q0 B | q0 B right
q0 a | qbcd B right
q0 b | qacd B right
q0 c | qabd B right
q0 d | qabc B right
-------------------------------------------------------------
// look for any of three targets ////////////////////////////
-------------------------------------------------------------
qbcd # | qa' # left
qbcd B,a | qbcd B,a right
qbcd b | qcd B right
qbcd c | qbd B right
qbcd d | qbc B right
-------------------------------------------------------------
qacd # | qb' # left
qacd B,b | qacd B,b right
qacd a | qcd B right
qacd c | qad B right
qacd d | qac B right
-------------------------------------------------------------
qabd # | qc' # left
qabd B,c | qabd B,c right
qabd a | qbd B right
qabd b | qad B right
qabd d | qab B right
-------------------------------------------------------------
qabc # | qd' # left
qabc B,d | qabc B,d right
qabc a | qbc B right
qabc b | qac B right
qabc c | qab B right
-------------------------------------------------------------
// look for any of two targets //////////////////////////////
-------------------------------------------------------------
qab # | qR # left
qab B,c,d | qab B,c,d right
qab a | qb B right
qab b | qa B right
-------------------------------------------------------------
qac # | qR # left
qac B,b,d | qac B,b,d right
qac a | qc B right
qac c | qb B right
-------------------------------------------------------------
qad # | qR # left
qad B,b,c | qad B,b,c right
qad a | qd B right
qad d | qa B right
-------------------------------------------------------------
qbc # | qR # left
qbc B,a,d | qbc B,a,d, right
qbc b | qc B right
qbc c | qb B right
-------------------------------------------------------------
qbd # | qR # left
qbd B,a,c | qbd B,a,c right
qbd b | qd B right
qbd d | qb B right
-------------------------------------------------------------
qcd # | qR # left
qcd B,a,b | qcd B,a,b right
qcd c | qd B right
qcd d | qc B right
-------------------------------------------------------------
// look for single target ///////////////////////////////////
-------------------------------------------------------------
qa #,a | qR #,B left
qa B,b,c,d | qa B,b,c,d right
-------------------------------------------------------------
qb #,b | qR #,B left
qb B,a,c,d | qb B,a,c,d right
-------------------------------------------------------------
qc #,c | qR #,B left
qc B,a,b,d | qc B,a,b,d right
-------------------------------------------------------------
qd #,d | qR #,B left
qd B,a,b,c | qd B,a,b,c right
-------------------------------------------------------------
// scan back to the beginning of the tape ///////////////////
-------------------------------------------------------------
qR # | q0 # right
qR B,a,b,c,d| qR B,a,b,c,d left
-------------------------------------------------------------
qa' # | qa'' # right
qa' B,a,b,c,d| qa' B,a,b,c,d left
-------------------------------------------------------------
qb' # | qb'' # right
qb' B,a,b,c,d| qb' B,a,b,c,d left
-------------------------------------------------------------
qc' # | qc'' # right
qc' B,a,b,c,d| qc' B,a,b,c,d left
-------------------------------------------------------------
qd' # | qd'' # right
qd' B,a,b,c,d| qd' B,a,b,c,d left
-------------------------------------------------------------
// write the output if we found one /////////////////////////
-------------------------------------------------------------
qa'' # | halt_accept # same
qa'' B,a,b,c,d| qE a right
-------------------------------------------------------------
qb'' # | halt_accept # same
qb'' B,a,b,c,d| qE b right
-------------------------------------------------------------
qc'' # | halt_accept # same
qc'' B,a,b,c,d| qE c right
-------------------------------------------------------------
qd'' # | halt_accept # same
qd'' B,a,b,c,d| qE d right
-------------------------------------------------------------
// erase the rest of the input tape /////////////////////////
-------------------------------------------------------------
qE # | halt_accept # same
qE B,a,b,c,d| qE # right
和{{1}在双素数状态下,扫描到最后,然后向后擦除,直到找到A
或上述符号之一。这意味着一些额外的状态,但在概念上是直截了当的。
此TM有24个状态,96个转换(如果完全展开)并且每次擦除至少一个符号;因此,在最坏的情况下,它的运行时间是二次的:输入大小4n,每个符号的n,算法执行n遍,每次通过n步的顺序,加上一些o(n ^ 2)的东西在末尾擦除胶带。
也许这就是你的想法,思想太复杂了。我承认写下来花了很长时间。然而,这在概念上非常简单,并且可能是单个磁带TM的最佳选择。