尽管这里有很多关于这个问题的问题,但是没有一个能帮助我解决这个问题。我理解递归是什么,我可以在2 ^ n-1次移动中轻松解决河内之塔,但我在Python中编写算法时遇到了麻烦。基本情况工作,但我似乎无法找到一种方法来翻译“将n-1磁盘移动到辅助挂钩,然后将最大磁盘移动到目标挂钩”进入阵列操作,我不明白为什么最后一个元素当我在递归调用中弹出它时,没有从数组中删除。
这是该计划:
peg_a = [1,0]
peg_b = []
peg_c = []
def hanoi(start,aux,target):
print(start,aux,target)
if len(start) == 1:
target.append(start.pop())
print(start,aux,target)
else:
hanoi(start[1:],target,aux)
target.append(start.pop())
print(start,aux,target)
hanoi(peg_a, peg_b, peg_c)
这就是印刷品:
[1, 0] [] []
[0] [] []
[] [] [0]
[1] [0] [0]
任何帮助?
答案 0 :(得分:3)
我认为一个问题是你的函数没有返回任何东西。您使用列表来保存bigs的内容,这些是可修改的对象,因此您可以将函数参数视为指向这些对象的指针。这可能有效,但问题是通过使用start[1:]
创建切片,您可以创建一个新列表,因此它不再是原始列表的“指针”。
一种解决方法可能仍然是使用输入参数作为列表的指针,而不是添加一些额外的整数函数参数,这些参数指示要移动的磁盘数量。
我就是这样做的:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs[target].append(pegs[start].pop())
print '%i -> %i: %s' % (start, target, pegs)
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
我没有使用3个不同的列表,因为在你的代码中它们会被交换,因此很难想象发生了什么。相反,我有一个pegs
变量,它是一个列表列表。在我的例子中,start
和target
是钉子的指数,我交换了它们。好消息是您现在可以打印各个步骤。快速演示:
pegs = [[4, 3, 2, 1], [], []]
hanoi(pegs, 0, 1, 4)
结果
0 -> 2: [[4, 3, 2], [], [1]]
0 -> 1: [[4, 3], [2], [1]]
2 -> 1: [[4, 3], [2, 1], []]
0 -> 2: [[4], [2, 1], [3]]
1 -> 0: [[4, 1], [2], [3]]
1 -> 2: [[4, 1], [], [3, 2]]
0 -> 2: [[4], [], [3, 2, 1]]
0 -> 1: [[], [4], [3, 2, 1]]
2 -> 1: [[], [4, 1], [3, 2]]
2 -> 0: [[2], [4, 1], [3]]
1 -> 0: [[2, 1], [4], [3]]
2 -> 1: [[2, 1], [4, 3], []]
0 -> 2: [[2], [4, 3], [1]]
0 -> 1: [[], [4, 3, 2], [1]]
2 -> 1: [[], [4, 3, 2, 1], []]
答案 1 :(得分:1)
您的代码存在两个问题:
start[1:]
不起作用,因为您正在创建列表的副本,因此不修改原始列表(见Bas'答案)。else
部分中的第二次递归通话,将aux
挂钩中的光盘堆叠到target
挂钩。要解决第一个问题,最简单的方法是添加一个aditional参数,指示要从start
重新定位到target
的光盘数量:
def hanoi(n, start, aux, target):
if n == 1:
target.append(start.pop())
else:
hanoi(n - 1, start, target, aux)
target.append(start.pop())
hanoi(n - 1, aux, start, target)
或更短:
def hanoi(n, start, aux, target):
if n > 0:
hanoi(n - 1, start, target, aux)
target.append(start.pop())
hanoi(n - 1, aux, start, target)