相互递归
都知道递归对于编程的重要性,今天就来谈谈相互递归。
若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)却没有尽头。