计算函数的递归调用

2024-10-05 10:20:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个加泰罗尼亚数字的递归代码。 我设法编写了递归调用,但由于某些原因,计数器不能正常工作。 例如,第7加泰罗尼亚语号码的呼叫数应为1215。 返回值需要是catalan数字和调用数的元组,例如:(4291215)。 原代码:

def catalan_rec(n):
    if n<=1:
        return 1
    res=0
    for i in range(n):
        res+=catalan_rec(i)*catalan_rec(n-i-1)
    return res

计数器代码:

^{pr2}$

提前谢谢!在


Tags: 代码returnifdef计数器原因res数字
2条回答

python允许您将一个变量(catalan.counter在下面的片段中)附加到函数对象,因此您不必一直传递计数器,也不需要全局变量:

def catalan(n):

    catalan.counter += 1

    if n <= 1:
        return 1
    res = 0
    for i in range(n):
        res += catalan(i) * catalan(n-i-1)
    return res

catalan.counter = 0

print(catalan(5))
print(catalan.counter)

并且看到函数被多次调用时使用相同的参数:为了提高效率,您可以使用^{};但这当然会破坏计算函数被调用次数的目的;您只能得到函数被调用的数字,而该函数是用一个唯一的n。在

^{pr2}$

这可能有点离题。。。但是,如果您需要带有单独计数器的函数的单独实例,closure可能正是您需要的:

def make_catalan():

    counter = 0

    def catalan(n):

        nonlocal counter
        counter += 1
        catalan.counter = counter

        if n <= 1:
            return 1
        res = 0
        for i in range(n):
            res += catalan(i) * catalan(n-i-1)
        return res

    return catalan

catalan_1 = make_catalan()
print(catalan_1(2))
print(catalan_1.counter)

catalan_2 = make_catalan()
print(catalan_2(3))
print(catalan_2.counter)

您需要将res+=catalan_rec_count(i,counter+1)*catalan_rec_count(n-i-1,counter+1)行分开,这样它就可以分别对递归结果和计数器进行操作,所以只需将它拆分为几个额外的行,而且在这种情况下,您不会将counter+1传递给递归调用,以便它独立于当前帧跟踪它的调用。。在

def catalan_rec_count(n,counter=1):
    if n<=1:
        return (1, counter) #remember to return the counter in this case too!
    res=0
    for i in range(n):
        #get the recursive results and counters for both calls
        #don't pass counter+1 to it, it should count how many times it is called on it's own
        partial1, inner_c1 = catalan_rec_count(i)
        partial2, inner_c2 = catalan_rec_count(n-i-1)
        #apply the logic with the actual result and add to the counter
        res+=partial1*partial2
        counter+= inner_c1 + inner_c2
    return (res,counter)

相关问题 更多 >

    热门问题