用Python表示图灵机的无限磁带最有效的方法是什么?

用Python表示图灵机的无限磁带最有效的方法是什么?,python,memory,data-structures,turing-machines,Python,Memory,Data Structures,Turing Machines,A根据规则表操纵无限长带上的符号 在我的例子中,磁带上的条目可以是0和1(二进制) 磁带从“空”开始,在正方向和负方向上都有无穷大的0。此磁带根据机器遵循的规则写入,可能会在未写入的边上添加0或1 既然磁带值是二进制的,那么当机器写入磁带时,有没有一种最有效的方法来在内存中表示它们,向左侧或右侧添加新值?显然,我不需要表示无限的零(未写入的磁带),但我确实需要扩展数据结构,将新值添加到磁带的末端 python列表可以做到这一点,如图所示,在左侧插入1: start_time = time.tim

A根据规则表操纵无限长带上的符号

在我的例子中,磁带上的条目可以是0和1(二进制)

磁带从“空”开始,在正方向和负方向上都有无穷大的0。此磁带根据机器遵循的规则写入,可能会在未写入的边上添加0或1

既然磁带值是二进制的,那么当机器写入磁带时,有没有一种最有效的方法来在内存中表示它们,向左侧或右侧添加新值?显然,我不需要表示无限的零(未写入的磁带),但我确实需要扩展数据结构,将新值添加到磁带的末端

python列表可以做到这一点,如图所示,在左侧插入1:

start_time = time.time()
tape = [0]*10000000
print tape[:10]
insertion_time = time.time()
tape = [1] + tape 
print tape[:10]
print "total execution time: ", time.time() - start_time
print "time to add entry: ", time.time() - insertion_time
这将产生:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
total execution time:  0.257364034653
time to add entry:  0.109524011612
使用list.insert会使速度提高23倍:

start_time = time.time()
tape = [0]*100000
print tape[:10]
insertion_time = time.time()
tape.insert(0, [1])
print tape[:10]
print "execution time: ", time.time() - start_time
print "time to add entry: ", time.time() - insertion_time
给予:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[1], 0, 0, 0, 0, 0, 0, 0, 0, 0]
execution time:  0.0270080566406
time to add entry:  0.00468802452087

是否有一种更有效的方式来表示二进制磁带,而不是使用<代码>清单>代码>对象?< /p> ,因为磁带两端是无限的,你必须考虑<代码>。(-inf,-1)索引范围。IMO的最佳表示形式是一对列表-一个用于非负范围,另一个用于负范围(索引反向)。当您移动到磁带的分配范围之外时,您只需将其附加到相应的列表中即可(与列表的前置操作不同,这是一个快速操作)

实施草案(使用增强版的
GrowingList
from):


您是否考虑过?请注意,
list.insert
是一个就地更新,您不需要分配结果。而不是
tape=tape.insert(0,[1])
使用
tape.insert(0,1)有趣的是,我会尝试DeGy,以前没有听说过。感谢List.Studio的插入。我现在能够执行代码并将更新。虽然DeQi比在两端追加数据的列表要快,但是在中间访问数据的速度较慢,请参阅手册中的警告。是吗​ 预编数据将改变现有项目的索引。至少就我而言,改变索引并不重要。我喜欢Leon的建议,即增加两个列表(一个索引颠倒)。我喜欢在两个索引列表中追加索引,其中一个索引颠倒-我将尝试此方法。@user391339我在答案中添加了一些快速而肮脏的草稿代码
class GrowingList(list):
    def __init__(self, default_value):
        self.default_value=default_value

    def __getitem__(self, i):
        return list.__getitem__(i) if i < len(self) else self.default_value

    def __setitem__(self, i, v):
        if i >= len(self):
            self.extend([self.default_value]*(i + 1 - len(self)))
        list.__setitem__(self, i, v)

class Tape:
    def __init__(self):
        self.pos_range=GrowingList(0)
        self.neg_range=GrowingList(0)

    def __getitem__(self, i):
        if i >= 0:
            return self.pos_range[i]
        else:
            return self.neg_range[-i-1]

    def __setitem__(self, i, v):
        if i >= 0:
            self.pos_range[i]=v
        else:
            self.neg_range[-i-1]=v

    def __repr__(self):
        start = -len(self.neg_range)
        end = len(self.pos_range)
        data = list(reversed(self.neg_range)) + self.pos_range
        return "Tape(range=[{}, {}), data={})".format(start, end, data)


t = Tape()
print(t)
t[4]=1
print(t)
t[-2]=1
print(t)
Tape(range=[0, 0), data=[])
Tape(range=[0, 5), data=[0, 0, 0, 0, 1])
Tape(range=[-2, 5), data=[1, 0, 0, 0, 0, 0, 1])