You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为汉诺塔(Tower of Hanoi)的每一步移动添加执行序号

没问题,我来帮你解决给汉诺塔移动步骤添加连续序号的问题~

给汉诺塔移动步骤添加连续序号的实现方案

核心实现思路

这里给你几个实用的思路,你可以根据自己的习惯选择:

  • 使用可变对象追踪步数:比如用一个只包含整数的列表(因为列表是可变类型,递归调用时能持续更新计数),避免使用全局变量带来的副作用。
  • 利用嵌套函数+nonlocal关键字:把递归函数放在一个外层函数里,用nonlocal声明计数变量,让内层递归函数可以修改外层的计数。
  • 让递归函数返回步数:每次递归完成后返回当前累计的步数,不过这种方式需要调整原函数的逻辑,把打印和步数计算结合起来。

修改后的完整代码示例

我这里用最直观的「可变对象追踪步数」方案来修改原代码,同时修正了原代码里的拼写错误,你可以直接运行:

def hanoi(disks, source, destination, auxiliary, step_counter):
    if disks == 1:
        step_counter[0] += 1
        print(f'{step_counter[0]}. move disk 1 from tower {source} to tower {destination}.')
        return
    hanoi(disks - 1, source, auxiliary, destination, step_counter)
    step_counter[0] += 1
    print(f'{step_counter[0]}. move disk {disks} from tower {source} to tower {destination}.')
    hanoi(disks - 1, auxiliary, destination, source, step_counter)

disk = int(input('Input Disk: '))
# 用列表来存步数,初始值为0(列表是可变对象,递归中修改会同步)
step_counter = [0]
hanoi(disk, 'A', 'B', 'C', step_counter)
total_moves = (2 ** disk) - 1
print(f"\nTotal Moves: {total_moves}")

代码关键点解释

  • 修正了原代码里的变量名拼写错误(比如Destination首字母大写统一为小写destination,递归函数里的disk改为disks)。
  • 新增step_counter参数,用[0]初始化:因为列表是可变对象,递归调用栈中所有修改都会同步到同一个计数器上。
  • 每次执行移动操作前先将计数器加1,再打印带序号的步骤。

测试示例

当输入磁盘数为3时,输出会是:

  1. move disk 1 from tower A to tower B.
  2. move disk 2 from tower A to tower C.
  3. move disk 1 from tower B to tower C.
  4. move disk 3 from tower A to tower B.
  5. move disk 1 from tower C to tower A.
  6. move disk 2 from tower C to tower B.
  7. move disk 1 from tower A to tower B.

Total Moves: 7

这样每一步都有了从1开始的连续序号,完全符合需求~

内容的提问来源于stack exchange,提问作者psyduck thunderstorm

火山引擎 最新活动