Python 之 Hanio 塔

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

在这个程序中,用数字 1 到 n 表示从小到大的 n 个盘子,local 表示原先堆放盘子的杆子,target 表示要将盘子最终移放到的杆子,temporary 表示在移放过程中需要用到的第三根杆子(可以理解为缓冲杆)。

def hanio(n,local,target,temporary):
	
	if n == 1:
		print('move {} from {} to {}'.format(n,local,target))
		return
	elif n > 1:
	
		hanio(n-1,local,temporary,target)
		print('move {} from {} to {}'.format(n,local,target))
		hanio(n-1,temporary,target,local)
		
hanio(2,'A','B','C')
'''
下面是输出:
move 1 from A to C
move 2 from A to B
move 1 from C to B
'''

简单理解

想通这个程序最关键的地方在于要相信 hanio(n, local, target, temporary) 这行代码能完美的实现这么一个任务:把 n 个盘子严格按照既定规则从 local 移放到了 target 上,移放过程中只要 n>1 就不可避免的要用到 temporary 杆。先别管这行代码是怎么做到的,只要相信他有这个能力就好。

然后接下来就是实现他这个能力了。首先考虑的是最简单的情况:n=1,这时只需要把 1 从 local 移放到 target 即可,紧接着输出一句:‘move 1 from local to target’,任务就这样完美的完成了。那么 n>1 的情况该怎么实现呢?接下来搞定他。这样想,这个工作其实只要简单的三步就可以搞定了:第一步,打开冰箱门;第二步,把大象放进冰箱;第三步,关上冰箱门。只要按顺序做好这三步,就真的可以把大象放进冰箱里了(?)。等一下,这扯到哪去了?其实我举这个例子是说明接下来的三个步骤给你的感觉不亚于上面的三步,真的会给人一种匪夷所思的感觉。好了回到正题,这三步是这样:第一步,把 local 顶上的 n-1 个盘子移放到 temporary 上;第二步,把 local 剩下的最底下的一个盘子移放到 target 上(这里要 print 一下:‘move n from local to target’);第三步,把 temporary 上的 n-1 个盘子移放到 target 上。好的,工作完成,我的意思是,我们到此已经实现了上述代码的能力了。

“好吧,我承认你这三步是已经实现了 hanio(n, local, target, temporary) 这行代码的能力,那你来说说 hanio(n-1, local, target, temporary) 这行代码的能力你是怎么实现的?因为你上面提到的三步里有两步都需要用到他。”

这就得回到开头我强调的部分了,我们要坚信 hanio(n, local, target, temporary) 这行代码能完美的完成他的任务,其实你也已经承认了,那么为什么 hanio(n-1, local, target, temporary) 就完成不了他的任务呢,他的任务好像还更容易完成一些呢!少了一个盘子,当然要容易一些,实际工作量少了足足有一半!(?)

尽管稍微有那么一点难以接受,这个程序到此毕竟是写好了,他现在就能完美的解决有 n 个盘子的汉诺塔问题了,前提是 n 不要太大,否则等出结果要花费你我都承受不了的时间!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值