Python:计算递归调用的执行

时间:2017-07-03 10:39:35

标签: python algorithm recursion counting

在学习Python 3.x时,我正在使用Euler问题来测试我的理解。在我为每个问题拼凑出一个可行的解决方案之后,我发现所发布的解决方案非常有启发性,并且在我努力奋斗之后我可以“吸收”新的想法。我正在研究Euler 024,我正在尝试一种递归方法。现在,我绝不相信我的方法是最有效或最优雅的,但是,我成功地生成了一整套排列,增加了价值(因为我从一个排序的元组开始) - 这是我想要的输出之一。另外,为了找到列表中的百万分之一(这是我想要的其他输出,但还不能得到),我试图计算每次创建排列时有多少,这就是我被卡住的地方。换句话说,我想要做的是每次到达基本情况时计算递归调用的数量,即完成的排列,而不是递归调用的总数。我在StackOverflow上找到了一些计算递归调用执行次数的非常清楚的例子,但我没有把这个想法应用到我的代码中。基本上我到目前为止尝试的问题是使用return语句“传回”“完成”排列的计数。我想我需要这样做,因为我的for循环创建了“stem”和“tail”元组。在高级别,要么我不能让计数器增加(所以它总是出现“1”或“5”)或“嵌套返回”只是在找到第一个排列后终止代码,具体取决于在哪里我把回报。任何人都可以帮助将计数插入到我的代码中吗?

首先我在SO中找到的“计数”代码我正在尝试使用:

def recur(n, count=0):
    if n == 0:
        return "Finished count %s" % count

    return recur(n-1, count+1)

print(recur(15))

接下来是我的排列代码,不计算在内。我尝试了很多方法,但没有一种方法可行。所以下面没有“计数”,只是在代码中我认为计数器需要递增的注释。

#
# euler 024 : Lexicographic permutations
#
import time
startTime= time.time()
#
def splitList(listStem,listTail):

    for idx in range(0,len(listTail)):
        tempStem =((listStem) + (listTail[idx],))
        tempTail = ((listTail[:idx]) + (listTail[1+idx:]))

        splitList(tempStem,tempTail)
    if len(listTail) ==0:
        #
        # I want to increment counter only when I am here
        #
        print("listStem=",listStem,"listTail=",listTail)

#
inStem = ()
#inTail = ("0","1","2","3","4","5","6","7","8","9")
inTail = ("0","1","2","3")

testStem = ("0","1")
testTail = ("2","3","4","5")

splitList(inStem,inTail)
#
print('Code execution duration : ',time.time() - startTime,' seconds')

提前致谢,

克里夫

2 个答案:

答案 0 :(得分:0)

为什么不为此编写发电机? 然后你可以停在n项目上("掉落而我< n")。

Mine解决方案正在使用itertools,但您可以使用自己的排列生成器。只需yield下一个序列成员而不是打印它。

from itertools import permutations as perm, dropwhile as dw
print(''.join(dw(
    lambda x: x[0]<1000000, 
    enumerate(perm('0123456789'),1)
).__next__()[1]))

答案 1 :(得分:0)

由于您似乎已经理解了基本问题,但只是想了解递归是如何发生的,所以您需要做的就是传递一个变量来告诉您在哪个调用堆栈中。您可以为函数添加第三个参数,并在每次递归调用时递增它:

def splitList(listStem, listTail, count):   
    for idx in range(0,len(listTail)):
        ...
        splitList(tempStem, tempTail, count)

    if len(listTail) == 0:
        count[0] += 1
        print('Count:', count)
        ...

现在,像这样调用这个函数(和以前一样):

splitList(inStem, inTail, [0])
相关问题