声明:
我写此文的目的是帮助和我一样在廖雪峰老师官网上学习Python3的同学更好的理解和学习Python的知识,所以本博文及后续文章会跟着我的学习进度来走,主要内容是廖雪峰老师官网Python资料中每节知识点后的复习题的答案和解析,有一些是我自己原创的,有一些是网上整理的大神写的简洁但对新手并不是很明了的答案,我会尽可能的给出我的解析。
题目:
请编写move(n,a,b,c)函数,它接收参数n,表示三个柱子中A,B,C中第一个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法。
期待输出:
A - - > C
A - - > B
C - - > B
A - - > C
B - - > A
B - - > C
A - - > C
答案:
def move(n,source,bridge,destination): if n == 1: print(source,'- - >',destination) else: move(n-1,source,destination,bridge) print(source,'- - >',destination) move(n-1,bridge,source,destination) move(3,'A','B','C')
解析:
这个答案是在廖雪峰老师官网上一名前辈的回答,刚接触这道题,我是拒绝的,因为我连题目都是没怎么看的太明白,我先是查阅了百度百科上关于汉诺塔的介绍,总算对题目有了清晰的了解,然后看了下廖雪峰老师官网上这道练习题后面前辈们给的解答,我再把前辈的经验和智慧从我的大脑里过一遍,然后尝试着根据我学习的感受和理解,在这里复述一下。
其实现在的我重新审视这个题的感受就是我最初想多了,想跑偏了,这就是个简单的盘子移动的问题,我建议在学到这里的时候你可以用身边现成的东西模拟一下这个汉诺塔实验,也许你不用往下看就可以弄明白。OK! 我们现在看代码的第一行,
def move(n,source,bridge,destination)给出答案的前辈用 source , bridge, destination 替换了a,b,c,含义分别是 source - 源柱、bridge - 过渡柱、destination - 目标柱。我们的母任务就是 把n个盘子,从 ” 源柱 “ 通过 ” 过渡柱 “ 移动到 ” 目标柱 “ 上。根据汉诺塔的规则,我们需要把这个母任务分成三个子任务来做:
1.把“ 源柱 ” 上面的n-1个盘,移动到“ 过渡柱 ”。
2.把” 源柱 “ 最下面的第n个盘移动到”目标柱“。
3.把第一步中的n-1个盘从”过渡柱“移动到”目标柱“,任务完成。
我们现在回到代码,第一行定义 move() 函数,这个前面也说过了,这个就是母任务,即从 source --> bridge -->destination。
2-3行代码,这个也简单,就是如果只有一个盘子,就可以从 源柱(source)直接移动到 目标柱(destination)。
5行代码,n-1代表了除留在最底下的盘子之外其他的盘子,这些盘子是不能直接停留在 目标柱(destination)上面的,我们必须先把这些盘子暂时放到 过渡柱(bridge),但是我们需要借助 目标柱(destination)把这些盘子从源柱(source)移动到 过渡柱(bridge),即 源柱(source)--> 目标柱(destination) --> 过渡柱(bridge)。
6行代码,就是子任务2,把留在最底下的盘子从 源柱(source)直接移动到 目标柱(destination),这个只需要 print 输出就可以了。
7行代码,需要把暂时放在 过渡柱(bridge)的那些盘子(n-1个)借助源柱(source)移动到 目标柱子(destination),so,understand?
完。
其实以上的解析在某些方面还是很抽象的,通过对前辈的学习和自己的理解,我也只是对很浅层的一个逻辑关系有了一个大概的理解,对于这个递归深层次的,比如说计算机在调用这个递归函数时的计算过程到底是怎样的我还是不清楚,所以希望有明白人能给我指点一下。
还是有很多想法没有写出来,因为怕有些同学看了之后不能有自己独立的思考空间。关于汉诺塔用Python实现还有两种答案,其实原理差不多,只不过表现方式不同,我会在下面给出,另外因为纯手动打字,肉眼检查,可能会有一些无重大影响的错误,请多包涵。
在汉诺塔百度百科下发现某前辈的给出的答案:
def move(n,a,b,c): if n == 1: print(a,'->',c) else: move(n-1,a,c,b) move(1,a,b,c) move(n-1,b,a,c) move(3,'A','B','C')
def move(n,a,b,c): if n == 0: return move(n-1,a,c,b) print('#%s --> %s'%(a,c)) move(n-1,b,a,c) move(3,'A','B','C')