字符串形式的汉诺塔(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}\nb:{1}\nc:{2}\ncount:{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是实现递归调用的关键,否则没有跳变的形参,递归就无从谈起.所以,在定义函数时,分清全局变量和局部变量,形参和实参的个数,极其关键!

posted @ 2018-06-18 23:26  永远怀着一颗学习的心  阅读(769)  评论(0编辑  收藏  举报