利用Python的内嵌函数和递归研究汉诺塔问题

         最近因为需要准备写爬虫等,所以开始学习Python。就汉诺塔问题来讲,简单的实现办法就是递归,没有什么可说的,懂递归的人随便用Java或C++都可以写出汉诺塔。但是现在我想知道给定层数下的汉诺塔完成后的最少步数是多少,大概值得菜鸟们稍微思考一会了,比如我。

        在正常的迭代函数中,定义一个计数值,每次循环便加一,最后将计数值打印出来即可。但这里使用了递归,就有了一个小问题。如果在递归函数中定义计数变量,那么每次递归都会重新初始为初始值,而如果将计数变量在函数体外定义(即全局变量),那么在函数中是无法直接使用的。因此,鉴于这个问题,我的解决方案是使用内嵌函数。

        这里涉及到了Python的语法问题,这里利用内嵌函数的大概思路是,在一个外部函数体内定义一个计数变量,然后在该函数体内再定义一个函数(即汉诺塔递归函数),在内部函数中通过使用nonlocal关键字,使得外部函数体内的计数变量可以在该内部函数中使用(也仅可以在该内部函数中使用),由此解决了计数的问题。

        具体实现的代码如下:

#汉诺塔

def hano():
    countt = 0
    def hanoi(n,x,y,z):
        nonlocal countt
        countt += 1
        if n == 1:
            print(x,' --> ',z)
            print("总共步数为:", countt)

        else:
            hanoi(n-1,x,z,y)

            print(x,' --> ',z)
            hanoi(n-1,y,x,z)

        # print("总共步数为:",countt)
    return hanoi

n = int(input("请输入汉诺塔的层数 :"))
hano()(n,'X','Y','Z')
          在上面的代码中需要注意的有两点:

         第一个是nonlocal的意义和实际如何调用该内嵌函数。nonlocal关键字在内嵌函数中使用,定义外部函数体中初始化的变量在该内部中不是局部变量,于是,之后的加一操作对于编译器来说就是合法的。而将该定义的函数一分为二来看,外部函数的作用仅是初始化一个计数变量和返回汉诺塔函数的结果,所以外部函数可以是无参传入。故外部函数的形参列表为空,且调用该函数的第一个括号对应为空。

        第二个需要注意的是打印语句的具体位置。准确地说,这并不是一个技术问题,只是为了能避免在递归过程中打印重复无必要的相同语句。就我注释的地方和现在实际使用的打印语句的位置,注释的位置打印出来有很多冗余,而在实际打印位置,每打印一次,说明最上层的汉诺塔被移动了一次。

        通过逐步调试和尝试递推,可以得到n层的汉诺塔完成移动需要2^n-1次,其中最上层的需要移动2^(n-1)次,第二层的需要2^(n-2)次,逐次至2^0。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值