我熟悉河内塔的递归功能。
现在我需要可视化动作,用星号表示光盘(我猜盘数=星号数是有道理的。)
是否有人提示如何使用
逐步绘制光盘移动 *
*** ***
***** ***** *
-------------------- ----------------------- ...
或类似的?
这是我教授提供的示例代码,我确实理解递归是如何工作的。但在Python的一次演讲之后,我必须说我对可视化任务感到有些不知所措。
def hanoi(n, p1, p2, p3):
if n==1:
print("move from %d to %d" %(p1, p3))
else:
hanoi(n-1, p1, p3, p2)
print("move from %d to %d " %(p1, p3))
hanoi(n-1, p2, p1, p3)
return
if __name__=='__main__':
j=int(input('Input the number of disk to be moved:\n'))
print('Number of disk to be move is %d \n'%j)
hanoi(j, 1, 2, 3)
非常感谢帮助!
答案 0 :(得分:1)
正如Phi Lipp所说,你需要一个国家的想法。
状态可以通过多种方式表示,但最终目标是您在屏幕上打印的X×Y字符网格。
例如,如果我们想要打印
*
***
*****
我们可以将其作为3x5数组存储在代码中。
[
[' ', ' ', '*', ' ', ' '],
[' ', '*', '*', '*', ' '],
['*', '*', '*', '*', '*'],
]
然后你可以循环并打印它。
for row in state:
for character in row:
print(character, end='')
丑陋的捷径将是
print('\n'.join(''.join(y) for y in x))
现在,如果您将此视为电影,则动画的每一帧都是X x Y数组。每个框架也是代码中的一个打印语句。困难在于改变行动,例如“从1移动到3”,成为州代表。
如果我们使用X by Y数组作为状态,则很难从space1移动到space2,因为字符数组不会告诉您有关环的数量以及环在空间中的大小1。这表明我们需要更好的状态。
这是非常开放的,但是一个解决方案是如果我们应用面向对象的编程,我们可以定义Ring和Tower对象,其中塔是环的集合。因此,动作会在塔之间移动环,并且Rings和Tower对象的状态用于创建X by Y数组。
我会懒惰并将一个环表示为一个整数,而塔是一个3 deques的数组。初始状态看起来像
from collections import deque
towers = [deque([1,2,3]), deque(), deque()]
现在你需要一个从塔U移动到塔V的功能:
def move_ring(from, to):
top_ring = from.popleft()
to.append(top_right)
最后,您需要从塔/环状态转换为可打印的X by Y数组。每次渲染每个塔都会更容易,每个环都在:
def render_ring(ring):
result = '*' * ring # the character * repeated ring times.
return result.center(user_input) # add the spaces required
def render_tower(tower):
result = []
for ring in tower:
result.append(render_ring(ring))
return result
最后,我们希望将塔组合成一个可打印的阵列。您可以使用zip。
def render_final(塔): tower_results = [] 塔楼塔楼: tower_results.append(render_tower(塔)) result = [] 对于zip中的all_rows(结果): result.append( ''。加入(ALL_ROWS)) 返回结果
现在您应该能够打印出结果并查看动画的帧。
这可以帮助您走上正确的轨道。请将上面的代码视为伪代码,因为它未经过测试。我也不建议使用整数和deques列表作为您的状态,因为这不会影响代码的清洁度。
还有一件事,如果你打印出结果,它将不会很漂亮,因为文本将打印和向下滚动。但是,如果您使用内置的curses库,则可以获得漂亮的输出。