在学习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')
提前致谢,
克里夫
答案 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])