如何在递归函数内创建计数器

时间:2013-02-24 14:29:40

标签: python recursion

def printMove(source, destination): 
    print('move From ' + str(source) + ' to destination ' + str(destination))
    count +=1
    print count

def Towers(n, source, destination, spare):
    if not count in  locals():
        count = 0
    if n == 1:
        printMove(source, destination)
        count +=1   
    else:
        Towers(n-1, source, spare, destination)
        Towers(1, source, destination, spare)
        Towers(n-1, spare, destination, source)

我写了这个剧本来解决“河内之塔”。 该脚本运行得非常好,但我也希望打印解决问题所需的动作数量。我只是无法弄清楚我怎么能把一个反计数的东西放在一边计算:

  1. 需要解决的动作次数。
  2. 执行“Towers”功能的次数。
  3. if not count in locals():条件是计算解决所需移动次数的失败尝试之一。我还在正确的轨道上吗?

    此外,这种算法有效吗?或者有更好的方法来解决这个问题吗?

    此外,有人可以告诉我河内塔的一些有用的应用和递归的优势吗?我唯一可以理解的是它的简单性。

6 个答案:

答案 0 :(得分:1)

一种方法是通过所有这些调用来运行计数器:

def towers(n, source, destination, spare, count=0):
    if n == 1:
        count += 1
        print('move From', source, ' to destination ', destination, count)
    else:
        count = towers(n-1, source, spare, destination, count)
        count = towers(1, source, destination, spare, count)
        count = towers(n-1, spare, destination, source, count)
    return count

towers(3, 1, 2, 3)

产量

move From 1  to destination  2 1
move From 1  to destination  3 2
move From 2  to destination  3 3
move From 1  to destination  2 4
move From 3  to destination  1 5
move From 3  to destination  2 6
move From 1  to destination  2 7

关于效率,http://en.wikipedia.org/wiki/Tower_of_Hanoi#Recursive_solution说:“通过数学归纳,很容易证明上述程序需要尽可能少的移动,并且所产生的解决方案是唯一具有此最小数量的解决方案。动作“。

递归的主要优点是这些解决方案往往优雅。对于某些问题,迭代解决方案表达比递归更复杂。

答案 1 :(得分:1)

您可以创建一个函数对象而不是函数:

class Towers:

    def __init__(self):
        self.count = 0

    def __call__(self, n, source, destination, spare):
        if n == 1:
            self.printMove(source, destination)
            self.count +=1   
        else:
            self(n-1, source, spare, destination)
            self(1, source, destination, spare)
            self(n-1, spare, destination, source)

    def printMove(self, source, destination):
        print('move From ' + str(source) + ' to destination ' 
              + str(destination))
        print(self.count)

towers = Towers()
towers(3, 1, 2, 2)

答案 2 :(得分:1)

我更喜欢这个版本,没有额外的参数' count':

def towers(n, source, destination, spare):
    count = 0
    if n == 1:
        print('move From', source, ' to destination ', destination)
        return 1
    else:
        count += towers(n-1, source, spare, destination)
        count += towers(1, source, destination, spare)
        count += towers(n-1, spare, destination, source)
        return count

print(towers(3, 1, 2, 3))

产量

move From 1  to destination  2
move From 1  to destination  3
move From 2  to destination  3
move From 1  to destination  2
move From 3  to destination  1
move From 3  to destination  2
move From 1  to destination  2
7

答案 3 :(得分:0)

最简单的方法是使用全局变量:

count = 0

def runTowers(...):
    global count
    count = 0
    Towers(...)

def Towers(...):
    global count
    count += 1
    ...

答案 4 :(得分:0)

上面的答案应该给你答案:)

在效率方面,看起来您的解决方案适用于n塔。如果您希望更有效地解决经典问题,请查看以下链接:

http://www.vogella.com/articles/JavaAlgorithmsTowersOfHanoi/article.html

最后,递归旨在制作非常简单的算法,可以使用基本代码执行复杂的计算。缺点是内存密集(每个调用在最后一次调用的堆栈上放置一个新的内存地址)。

答案 5 :(得分:0)

没有时间暂停它,它将很快达到递归限制

import time
def loop_forever(count):
    if count == 0:
        print(count)
        time.sleep(1)
        loop_forever(1)
    if count > 0:
        print(count)
        time.sleep(1)
        loop_forever(count + 1)


loop_forever(0)