目前,我正在尝试开发图灵机。它应该接受一个序列 k、x1、x2、...、xn,其中 k 是正整数,对于每个 i,xi 是非负整数作为输入。所有数字都将以 的形式编码a^k b a^x1 b a^x2 b ..... b a^xn
。
对于输出,它应该输出第k个元素的值。
例如:如果我的输入是 aaababaaaaabaa(k = 3, 第一个元素 = 1, 第二个元素 = 5, 第三个元素 = 2)
在这种情况下,图灵机应将输出显示为 aa(2)。我目前面临的问题是,我不知道如何跟踪数字 k,因为没有计数器/内存来存储值 k。此外,即使我跟踪了第 k 个元素,我也不知道如何输出该值
我曾尝试使用标记符号技术,即每次从 k 中读取 a 时,它都会将其写为 A 并向右查找 b。如果找到 b,则将其写为 B 并返回查找 A。在这种情况下,我可以跟踪每个 A 和 B(我的想法就像用每个 b 取消每个 a)。但最后,当没有更多的 A 和 B 时,我不知道如何转到第 k 个元素并输出值。
希望有人能帮助我。
p/s: 我正在使用 Tuatara 模拟器
谢谢。
a
您可以通过将属于 𝑘 编码的每个字符映射到 来跟踪 𝑘 的减少数量b
。标记属于这种对的字符的想法很好。一旦没有剩余的(未标记的)字符a
,您就可以开始删除字符,直到(包括)第一个未标记的b
。a
后面的 应该保留。最后删除该系列 后面的任何字符a
。这种方法实际上会选择第k+1 个数字,因此只需删除第一个数字
a
而不将其映射到 ab
来补偿这一点。您在评论中提到,您使用的是单侧图灵机,其右侧无限,但左侧有一个起点,头部也从那里开始。正如您所指出的,预期输出应在磁带的开头左对齐,因此您需要一些额外的状态和转换来将找到的序列“移动”
a
到左侧。您可以用不同的方式做到这一点。一种是删除最右边的序列a
,并在序列的左侧写入一个。重复此操作,直到到达磁带的开头,我们可以用字母“A”标记。我还会删除
a
属于 𝑘 的,而不是用大写字母标记它们,因为最终你还是会想要删除或替换它们。这是一个可能的转换表:
初始状态为“start”,空白用“_”表示。如果输入有解决方案,最终状态将为“accept”。
以下是使用该转换表的可运行实现: