簡體   English   中英

如何在遞歸函數中創建計數器

[英]How to create a counter inside a recursive function

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. “塔”功能被執行的次數。

if not count in locals():條件是對嘗試解決的移動次數進行計數的失敗嘗試之一。 反正我在正確的軌道上嗎?

另外,此算法有效嗎? 還是有更好的方法來解決這個問題?

此外,有人可以告訴我河內之塔的一些有用應用以及遞歸的優勢嗎? 我唯一能想到的就是它的簡單性。

一種方法是讓計數器通過所有這樣的調用:

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說:“通過數學歸納的方法,很容易證明上述過程需要最少的移動次數,並且產生的解決方案是只有最少移動次數的一個。”。

遞歸的主要優點是這些解決方案往往很優雅。 對於某些類型的問題,迭代解決方案的表達方式比遞歸的更為復雜。

您可以創建一個函數對象而不是一個函數:

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)

我更喜歡這個版本,沒有額外的參數'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

最簡單的方法是使用全局變量:

count = 0

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

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

上面的答案應該給你你的答案:)

在效率方面,您的解決方案似乎可用於n座塔。 如果您想更有效地解決經典問題,請查看以下鏈接:

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

最后,遞歸旨在設計出非常簡單的算法,可以使用基本代碼執行復雜的計算。 缺點是它占用大量內存(每個調用在上一次調用的堆棧上放置一個新的內存地址)。

沒有時間暫停它,它將很快達到遞歸限制

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM