zoukankan      html  css  js  c++  java
  • 字符串形式的汉诺塔(Tower of Hanoi)Python语言实现_18.6.19更新

    代码优势:模块化做的很好,找到了通过写出前4-5次的数学表达,找到了规律并将其化成代码__18.6.19:昨天的程序将激励想复杂了,这里最简基例是搬1个汉诺塔,最初想复杂了想成了2个!导致if和else语段有重合内容,代码已更新,减少了几行,增加了计次功能!.

    代码劣势:规则化欠佳,因python无指针(网上说的,还不确定),没有学到python中类似c语言指针的函数,造成本来一个模块不得不分解为6个模块相互调用.并且函数封装不好,即因为不会类指针方法,所以用函数操作了全局变量.

    上代码1:

    #这里最简基例是搬1个汉诺塔,最初想复杂了想成了2个
    def ac(k):
        global a
        global b
        global c
        global count
        if k==1:
            c+=a[-1];a=a[:-1];count+=1
        else:
            ab(k-1)
            c+=a[-1];a=a[:-1];count+=1
            bc(k-1)
    
    def ab(k):
        global a
        global b
        global c
        global count
        if k==1:
            b+=a[-1];a=a[:-1];count+=1
        else:
            ac(k-1)
            b+=a[-1];a=a[:-1];count+=1
            cb(k-1)
    def cb(k):
        global a
        global b
        global c
        global count
        if k==1:
            b+=c[-1];c=c[:-1];count+=1
        else:
            ca(k-1)
            b+=c[-1];c=c[:-1];count+=1
            ab(k-1)
    
    def ca(k):
        global a
        global b
        global c
        global count
        if k==1:
            a+=c[-1];c=c[:-1];count+=1
        else:
            cb(k-1)
            a+=c[-1];c=c[:-1];count+=1
            ba(k-1)
    
    def ba(k):
        global a
        global b
        global c
        global count
        if k==1:
            a+=b[-1];b=b[:-1];count+=1
        else:
            bc(k-1)
            a+=b[-1];b=b[:-1];count+=1
            ca(k-1)
    
    def bc(k):
        global a
        global b
        global c
        global count
        if k==1:
            c+=b[-1];b=b[:-1];count+=1
        else:
            ba(k-1)
            c+=b[-1];b=b[:-1];count+=1
            ac(k-1)
    
    a='fedcba9876543210'
    b=''
    c=''
    count=0
    ac(len(a))
    print('a:{0}
    b:{1}
    c:{2}
    count:{3}'.format(a,b,c,count))

    输出为:

    a:
    b:
    c:fedcba9876543210
    count:65535

    逻辑思维的结果为2^n-1,与计算思维的结果相同.也证明了这是最简单的方法.

    F7一步步看了9层汉诺塔中a,b,c字符串的变换过程,发现代码至少在9层是正确的,20层的时候也和代码2相呼应计次为1048575,所以基本上可以确定算法是正确的.

    举一反三:上述代码是字符串形式的汉诺塔,容量有限且处理16个以上元素时表示不方便,后面会写一个列表形式的汉诺塔

    18.6.19日补充这个程序实现了汉诺塔搬运的仿真,当时刚看到题目就按下了暂停键,结果今天发现老师只实现了汉诺塔实现方法的打印,还是比较刁钻的,这很有启发性,在学习阶段探索仿真固然好,但商业化的项目中,设计算法前还是看清要求,因为如果只是要求给出汉诺塔实现方法则要简单许多,which只用一个模块使用print函数打印就行了!

    下面给出打印汉诺塔实现方法的程序,这个类似于物理实现,要简单一点.

    上代码2:

    def f(a,b,c,k):
        global count
        if k==1:
            print('{0}->{1}'.format(a,c),end=';')
            count+=1
        else:
            f(a,c,b,k-1)
            print('{0}->{1}'.format(a,c),end=';')
            count+=1
            f(b,a,c,k-1)
    
    s='a'
    m='b'
    t='c'
    c=16
    count=0
    f(s,m,t,c)
    print('count:{0}'.format(count))

    同代码1,实现16层汉诺塔搬运,这里count仍是65535,是正确的.

    心得:要改变字符串(汉诺塔)的值,在不了解Python指针(还不知道有没有,暂时没学到)的情况下,不能将全局变量a,b,c作为函数的形参,所以必须用6个模块分别实现塔(列表或字符串)之间的塔层(元素)交换.而引入形参k是实现递归调用的关键,否则没有跳变的形参,递归就无从谈起.所以,在定义函数时,分清全局变量和局部变量,形参和实参的个数,极其关键!

  • 相关阅读:
    Visual Studio调试器指南---Disassembly窗口
    Visual Studio调试器指南---Register窗口
    Visual Studio调试器指南---Threads窗口
    关于System.Convert.ToInt16(float value)抛异常System.OverflowException---值对于 Int32 太大或太小的原因的探究
    关于System.OverflowException异常
    Visual Studio调试器指南---Memory 1-4窗口
    关于异常System.NullReferenceException
    关于C++标准异常之std::out_of_range
    VC调试器高级应用----高级断点篇
    Visual Studio调试器指南---CallStack窗口
  • 原文地址:https://www.cnblogs.com/zhangziyan/p/9196725.html
Copyright © 2011-2022 走看看