ChuckCheng 发表于 2018-9-4 13:33:44

关于汉诺塔里求次数的一个print的小问题

本帖最后由 ChuckCheng 于 2018-9-4 13:35 编辑

看了汉诺塔的视频,想求求每次递归的次数,程序没问题,有个小问题是关于,print的,为什么直接把函数写在print里,显示的次数会是正确的两倍??这是为什么
t=0
def hanoi(n,x,y,z):
   
    global t
   
    if n==1:
      
      t+=1
      #print(x,'->',z)##只有一个盘子时直接移动到第三个盘子
    else:
      hanoi(n-1,x,z,y)##假设已经将所有前n-1个盘子移动y以后
      
      t+=1
      #print(x,'->',z)###将最后一个盘子移动到第三个柱子
      hanoi(n-1,y,x,z)##然后将前面n-1个盘子从中间的柱子y移动到第三根柱子上
   
    return t
f=hanoi(3,'x','y','z')
print('共计需要%d步' %hanoi(3,'x','y','z')) ## 显示为14步,正确答案的2倍
print(f)#3显示正确答案7步
print('共计需要%d步' %f)##显示7步

claws0n 发表于 2018-9-4 13:41:24

7 步 ?

ChuckCheng 发表于 2018-9-4 14:16:06

claws0n 发表于 2018-9-4 13:41
7 步 ?

你把程序中的print的#删了·····你不要删,返回的的t就是 递归的次数

我把##删了以后,跑出来的结果如下
x -> z
x -> y
z -> y
x -> z
y -> x
y -> z
x -> z
x -> z
x -> y
z -> y
x -> z
y -> x
y -> z
x -> z
共计需要14步(这里还是显示14步,不理解)
7
共计需要7步

ChuckCheng 发表于 2018-9-4 14:18:01

claws0n 发表于 2018-9-4 13:41
7 步 ?

问题出在print('共计需要%d步' %hanoi(3,'x','y','z'))打出来是14
print('共计需要%d步' %f)打出来是7,这就是我疑惑的地方,,实际就是7个移动完成汉诺塔··

FC的注册很坑 发表于 2018-9-4 14:27:25

本帖最后由 FC的注册很坑 于 2018-9-4 14:28 编辑

因为做了2遍啊,你把f=hanoi(3,'x','y','z')注释掉,直接print('共计需要%d步' %hanoi(3,'x','y','z'))就是7步
因为t=0是在上面的
f=hanoi(3,'x','y','z')调用了一遍,t=7了
然后print里又调用了一遍,在t=7的基础上又加了7次,所以就是14了
而直接print(f)就是第一次的t=7,所以输出是7
就是每次的调用没有把t还原成t=0

lirenkonghong 发表于 2018-9-4 14:29:07

你将“print('共计需要%d步' %hanoi(3,'x','y','z')) ”中的%hanoi(3,'x',;y','z')改为%f,因为访问的次数多了一倍,输出的次数就多了一倍

claws0n 发表于 2018-9-4 14:34:03

ChuckCheng 发表于 2018-9-4 14:18
问题出在print('共计需要%d步' %hanoi(3,'x','y','z'))打出来是14
print('共计需要%d步' %f)打出来是7, ...

哈哈,明白您的问题了。因为 global t 。你在 print 调用 hanoi(),会计算多一次。所以是 print('共计需要%d步' %f)。
global + 再次调用函数

ChuckCheng 发表于 2018-9-4 15:03:07

claws0n 发表于 2018-9-4 14:34
哈哈,明白您的问题了。因为 global t 。你在 print 调用 hanoi(),会计算多一次。所以是 print('共计需 ...

谢谢~~~

geen 发表于 2018-9-4 16:25:58


处理问题我喜欢尽可能的简单化,我用的是sum的方式,很好处理哦。

s = 0
def hanoi(n,x,y,z):
    global s
    i = 0
    if n == 1:
      print(x,'-->',z)
      i += 1
    else:
      hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上
      print(x,'-->',z)#将最底层的最后一个盘子从x移动到z上
      hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上
      i += 1
    s = s + i
n = int(input('请输入汉诺塔的层数:'))
hanoi(n,'A','B','C')
print(s)

ChuckCheng 发表于 2018-9-4 20:11:47

claws0n 发表于 2018-9-4 14:34
哈哈,明白您的问题了。因为 global t 。你在 print 调用 hanoi(),会计算多一次。所以是 print('共计需 ...

请问一个问题,如果我如那样连续多次调用函数,可是全局变量t却无法清0,这样每次得的递归次数都是累计,有没有办法修改,保证每次计算出的递归次数就是当下的递归次数·····

ChuckCheng 发表于 2018-9-4 20:12:42

geen 发表于 2018-9-4 16:25
处理问题我喜欢尽可能的简单化,我用的是sum的方式,很好处理哦。

s = 0


连续调用两次函数,s还是会是两次调用的递归次数之和,并非的单次调用的次数,有能修改一下吗···

claws0n 发表于 2018-9-5 00:18:03

ChuckCheng 发表于 2018-9-4 20:11
请问一个问题,如果我如那样连续多次调用函数,可是全局变量t却无法清0,这样每次得的递归次数都是累计, ...

def hanoi(n, x = 'x', y = 'y', z = 'z'):
    count = 0               #必须先有一个局部变量
    def hanoi_counter(n, x, y, z):      #函数的封装
      nonlocal count    #改用 nonlocal 非局部变量
      count += 1
      if n == 1:
##            print(x +' -> '+ z)
            return count
      else:
            hanoi_counter(n-1,x,z,y)
##            print(x +' -> '+ z)
            hanoi_counter(n-1,y,x,z)
    hanoi_counter(n,x,y,z)      #这里要调用才会启动计数
   
    return count    #返回计数结果

print('testing\n')
for i in range(1,5):
    print('final result',hanoi(3))

geen 发表于 2018-9-5 14:37:48

FC的注册很坑 发表于 2018-9-4 14:27
因为做了2遍啊,你把f=hanoi(3,'x','y','z')注释掉,直接print('共计需要%d步' %hanoi(3,'x','y','z'))就是 ...

{:10_275:}

ChuckCheng 发表于 2018-9-5 16:41:57

claws0n 发表于 2018-9-5 00:18


谢谢,厉害,够学习了··很多东西

claws0n 发表于 2018-9-5 16:47:01

ChuckCheng 发表于 2018-9-5 16:41
谢谢,厉害,够学习了··很多东西

记得采纳最佳答案哦~~{:10_254:}
页: [1]
查看完整版本: 关于汉诺塔里求次数的一个print的小问题