相互递归

相互递归

都知道递归对于编程的重要性,今天就来谈谈相互递归。

若2者之间存在递推关系,则可以使用相互递归。下面举2个例子。

求pi

根据公式 # pi/4 = 1 - 1/3 + 1/5 -1/7 + 1/9 - ...


def calPi(n):
    piDiv4 = 0

    def neg(a):
        nonlocal piDiv4
        if a > 1:
            piDiv4 -= 1/a
            pos(a-2)
        #当a<=1, 函数终结

    def pos(b):
        nonlocal piDiv4
        piDiv4 += 1/b
        neg(b-2)

    
    pos(n) if ( (n//2) % 2 == 0) else neg(n)
    print(4*piDiv4)

上面的相互递归,只要一方终结、另一方也会因此结束(此处的终结指不再return函数,结束相互递归的过程),neg与pos的关系还能写成下面的方式:

#上面是neg终结、此处是pos终结

    def neg(a):
        nonlocal piDiv4
        piDiv4 -= 1/a
        pos(a-2)

    def pos(b):
        nonlocal piDiv4
        if b > 1:
            piDiv4 += 1/b
            neg(b-2)
        else:
            piDiv4 += 1	  #终结

通常相互递归可以通过增加一个参数来抵消掉。

def calPi2(n):
    flag = 1 if (n//2) % 2 == 0 else -1
    piDiv4 = 0
    def calIt(n,flag):
        if n >= 1:
            nonlocal piDiv4 
            piDiv4 += flag/n
            calIt(n-2, -flag)

    calIt(n, flag)
    print(4*piDiv4)

当知道2者之间的递推式,用相互递归实现比较简单

#求数列q的第n项
#规定q(1)=1、S(n)=q(1)+q(2)+...+q(n)、q(n)=1+S(n-1)

def q(n):
    def seqSum(n):
        if n == 0:
            return 0	#终结
        else:
            return q(n) + seqSum(n-1)    #这里使用了一个推导的数学结论:S(n) = q(n) + S(n-1)

    if n >= 1:
        return 1 + seqSum(n-1)

对于上面的相互递归,只能由函数seqSum来终结递归过程,可见当seqSum终结,函数q必然结束,因为q返回的是1 + seqSum(n-1)

但是如果改为下面:

def q(n):
    def seqSum(n):
        return q(n) + seqSum(n-1)    

    if n > 1:
        return 1 + seqSum(n-1)
    else:
        return 1	#终结

这种情况下由函数q来终结,但是会死循环,因为函数seqSum返回值为q(n) + seqSum(n-1), 它能否终结由自身和函数q共同决定!即使q(n)结束返回一个值,seqSum(n-1)却没有尽头。

posted @ 2020-03-26 11:52  friedCoder  阅读(369)  评论(0编辑  收藏  举报