相互递归

Posted friedcoder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了相互递归相关的知识,希望对你有一定的参考价值。

相互递归

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

若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)

    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)却没有尽头。

以上是关于相互递归的主要内容,如果未能解决你的问题,请参考以下文章

片段相互重叠

CSP核心代码片段记录

相互递归

executePendingTransactions 的递归入口

nodejs常用代码片段

终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系。有了这个,就有了主动,带不带句柄完全看需要。(代码片段