You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求基于ASCII星号的汉诺塔移动分步可视化实现示例与提示

汉诺塔星号可视化实现思路&示例

嘿,刚学一节Python就能琢磨汉诺塔的可视化,这想法太赞了!既然你已经懂递归逻辑,那咱们就把注意力放在用星号分步绘制状态上,核心思路其实很简单:维护三个塔的当前状态,每次移动圆盘后就把整个塔的布局画出来。下面给你一步步拆解,还有超适合新手的示例代码~

核心思路拆解

  • 用列表存塔的状态:每个塔对应一个列表,列表里的元素是圆盘的编号(比如圆盘1对应*,圆盘3对应***),列表的最后一个元素就是塔最顶端的圆盘,这样移动圆盘时用pop()和append()就很方便。
  • 每次移动后绘制状态:写一个专门的画图函数,接收三个塔的列表,然后从上到下逐层打印每个塔的圆盘(没有圆盘的位置就空着),最后打印横线代表柱子。
  • 递归+可视化绑定:在你已经理解的递归移动逻辑里,每次完成一次圆盘移动后,调用画图函数,同时打印移动说明,这样就能看到每一步的变化。

新手友好的示例代码

def draw_towers(tower_a, tower_b, tower_c):
    # 先找到最大的圆盘编号,用来计算对齐宽度和柱子横线长度
    all_disks = tower_a + tower_b + tower_c
    max_disk = max(all_disks) if all_disks else 0
    # 每个圆盘的显示宽度:编号*2-1(比如圆盘3对应5个字符宽度,保证星号居中对称)
    disk_width = max_disk * 2 - 1

    # 从最上层到最下层绘制(循环次数等于最大圆盘数)
    for level in range(max_disk, 0, -1):
        # 逐个检查每个塔当前层有没有圆盘
        for tower in [tower_a, tower_b, tower_c]:
            # 如果当前塔的长度 >= level,说明这一层有圆盘
            if len(tower) >= level:
                disk_num = tower[level-1]
                # 生成对应星号并居中对齐
                print(f"{disk_num*'*':^{disk_width}}", end=" | ")
            else:
                # 没有圆盘就打印对应宽度的空格
                print(f"{' ':^{disk_width}}", end=" | ")
        print()  # 换行到下一层
    
    # 打印柱子的横线
    line = "-" * disk_width
    print(f"{line} | {line} | {line}")
    # 打印塔的标签,方便区分
    print(f"{'A':^{disk_width}} | {'B':^{disk_width}} | {'C':^{disk_width}}\n")

def hanoi(n, source, target, auxiliary, towers):
    if n == 1:
        # 移动最顶端的圆盘
        disk = towers[source].pop()
        towers[target].append(disk)
        # 打印移动说明并绘制当前状态
        print(f"移动圆盘 {disk} 从 {source} 到 {target}")
        draw_towers(towers['A'], towers['B'], towers['C'])
        return
    hanoi(n-1, source, auxiliary, target, towers)
    # 移动当前层级的圆盘
    disk = towers[source].pop()
    towers[target].append(disk)
    print(f"移动圆盘 {disk} 从 {source} 到 {target}")
    draw_towers(towers['A'], towers['B'], towers['C'])
    hanoi(n-1, auxiliary, target, source, towers)

# 初始化塔的状态:比如3个圆盘,A塔从下到上是3、2、1
num_disks = 3
towers = {
    'A': list(range(num_disks, 0, -1)),
    'B': [],
    'C': []
}

print("初始状态:")
draw_towers(towers['A'], towers['B'], towers['C'])
# 启动递归移动
hanoi(num_disks, 'A', 'C', 'B', towers)

代码说明(专为新手准备)

  1. draw_towers函数:

    • 先确定最大圆盘的编号,保证所有柱子的横线长度一致,圆盘星号能居中对齐,视觉上更舒服。
    • 从最高层往下绘制,每个塔的当前层如果有圆盘就打印对应星号,没有就打印空格,完美还原塔的立体布局。
    • 最后补充横线和塔标签,让你一眼分清A、B、C三个塔。
  2. hanoi递归函数:

    • 把你已经理解的递归逻辑和塔的状态绑定,每次完成圆盘移动(pop取出、append放入)后,立刻调用draw_towers画出当前状态,同时打印移动的圆盘编号和路径,每一步都清晰可见。
    • 用字典存储三个塔,比单独的列表更直观,方便传递和操作。

运行效果示例

你运行代码后,会看到类似这样的分步输出(以3个圆盘为例):

初始状态:

B

移动圆盘 1 从 A 到 C
| | *

B

...(后续每一步都会实时更新塔的状态)

这样每一步的圆盘移动都能直观看到,完全符合你想要的星号+横线的格式~

内容的提问来源于stack exchange,提问作者Phi Lipp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:11:13