如何为汉诺塔(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时,输出会是:
- move disk 1 from tower A to tower B.
- move disk 2 from tower A to tower C.
- move disk 1 from tower B to tower C.
- move disk 3 from tower A to tower B.
- move disk 1 from tower C to tower A.
- move disk 2 from tower C to tower B.
- move disk 1 from tower A to tower B.
Total Moves: 7
这样每一步都有了从1开始的连续序号,完全符合需求~
内容的提问来源于stack exchange,提问作者psyduck thunderstorm




