1.问题描述
有5个人坐在一起,问第5个人多少岁,他说比第4个人大2岁。问
第4个人多少岁,他说比第3个人大2岁。问第3人多少岁,他说比第2个
人大2岁。问第2个人多少岁,他说比第1个人大2岁。最后问第1个人多
少岁,他说他是10岁。编写程序,求出当输入某个人时其对应的年
龄。
2.问题分析
在分析该问题前先介绍函数递归调用的基础知识。
1)函数递归调用的定义:如果在调用一个函数的过程中又出现直
接或间接地调用该函数本身,则称为函数的递归调用。Python语言中允
许函数进行递归调用。
2)程序中递归调用的方式:直接递归调用,即函数直接调用本
身。例如:

def f(x):
......
y = f(n) # 调用自身
.....
return y

在调用函数f()的过程中,又要调用f()函数,这就是函数的直接递
归调用。
间接递归调用,即函数间接调用本身。例如:

def f1(x):
......
z = f2(y)
......
return 2*z
def f2(t):
.....
c = f1(a)
.....
return 3+c

在上面的代码中定义了两个函数f1()和f2()。在调用f1()函数的过程
中,f1()又调用了函数f2(),而在调用函数f2()的过程中,又调用了
f1()。
注意: 在递归调用中不能出现无终止的调用,只能是有限次的递
归调用,即必须有递归结束条件。因此,在代码中一定要有控制递归
调用终止的语句。一般可以采用if语句来控制只有在某一条件成立时才
继续执行递归调用,否则不再继续递归。
了解了递归调用的基础知识后,现在对本节中提出的问题进行分
析。
该问题是一个递归问题。要求出第5个人的年龄,则必须先知道第
4个人的年龄,显然第4个人的年龄也是未知的,但可以由第3个人的年
龄推算出来。而想知道第3个人的年龄,又必须先知道第2个人的年
龄,而第2个人的年龄取决于第1个人的年龄。
又已知每个人的年龄都比其前一个人的年龄大2,因此根据题意,
可得到如下几个表达式:

age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=10

归纳上面的5个表达式,用数学公式表达为:

python怎么计算年龄 python计算年龄的方法_算法

        在上面的公式中,当n>1时,求第n个人的年龄是通过一个公式来
表达的。根据式①,我们可以画图来表示求第n个人年龄的过程,如图
9.6所示即为求解第5个人年龄的过程。
求解第n个人的年龄分成两个阶段。第一个阶段是“回推”过程,第
二个阶段是“递推”过程。
在“回推”过程中,利用的是n>1时的公式age(n-1)+2。要求的是第n
个人的年龄,因此首先将第n个人的年龄回推到第(n-1)个人的年龄,但
第n-1个人的年龄仍然未知,因此需要继续回推到第(n-2)个人的年龄,
第(n-2)个人的年龄仍然未知,需要继续向前回推,如此下去,一直回
推到第1个人的年龄。而第一个人的年龄是已知的,因此,第一阶段
的“回推”过程结束,开始第二阶段的“递推”。
在“递推”过程中,从第1个人的年龄可以推出第2个人的年龄,从
第2个人的年龄可以推出第3个人的年龄,如此下去一直递推到第5个人
的年龄。

python怎么计算年龄 python计算年龄的方法_python怎么计算年龄_02

 

在图9.6中,通过“回推”和“递推”两个过程,最终可得到第5个人的
年龄为18岁。
3.算法设计
理解了问题分析中的递归处理过程后,算法设计就非常简单了。
只需要将式①转换成一个函数,然后在main()函数中调用它就可以了。
4.完整的程序
根据上面的分析,编写程序如下:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 递归解决年龄问题
#递归计算年龄
def age(n):
if n == 1:
x = 10
else:
x = age(n-1) + 2
return x
if __name__ == "__main__":
n = int(input("请输入n值:")) # n表示第几个人
# 调用age()函数,计算第n个人的年龄
print("第 %d 个人的年龄为:%d" %(n, age(n)))

 程序分析:
虽然问题分析过程比较复杂,但该问题的程序代码非常简单,在
main()函数中通过调用age(n)函数就可以获知第n个人的年龄。
age()函数总共被调用了n次,其中age(n)是由main()函数进行调用
的,而其余的n-1次都是由age()函数自身调用的,即age()函数递归调用
了n-1次。
假设n=5,则age()函数总共被调用了5次,age()函数递归调用了4
次。
要注意的是,每次调用age()函数时并不会马上获得年龄值,而是
不断地进行递归调用,直到调用到age(1)时才有确定的年龄值,然后再
从age(1)一步步地递推回去。

age(n)函数的调用过程如图9.7所示。

python怎么计算年龄 python计算年龄的方法_算法_03

5.运行结果

在PyCharm下运行程序,屏幕上提示“请输入n值:”,对该题而

言,n的最大取值为整数5。此处输入n的值为5,则计算出第5个人的年

龄为18。运行结果如图9.8所示。

python怎么计算年龄 python计算年龄的方法_算法_04

 

6.问题拓展
由该题的分析过程可知,递归的问题都可以分为“回推”和“递推”两
个阶段,而且必须存在一个能够结束递归过程的条件,如本题中的
age(1)=10,否则递归过程会无限制地进行下去而无法结束。
下面对递归法做一总结。
递归是设计和描述算法的一种强有力的工具。能够采用递归来描
述的算法通常具有一些特征:为求解规模为n的问题,首先要将它分解
成规模较小的问题,然后通过这些小问题的解,能够方便地构造出大
问题的解,同时,这些规模较小的问题也能够采取同样的分解方法分
解成规模更小的问题,并能够通过这些更小问题的解构造出规模较大
问题的解。特别地,当问题规模n=0或n=1时,能直接获得问题的解。
递归算法的执行过程分为“回推”和“递推”两个阶段。
·在回推阶段,是把较复杂的问题(规模为n)的求解递推到比原问
题简单一些的问题(规模小于n)的求解。例如本例中,要求解
age(n),先把它递推到求解age(n-1),而要计算age(n-1),又必须先计算
age(n-2),以此类推,直到age(1)为止。需要注意的是,在递推阶段,
必须要有能够终止递归的条件。如本例中n为1时,递推可终止。
·在递推阶段,当获得最简单情况的解时,如本题中得到age(1)的
值,逐级返回,依次得到较复杂问题的解,最终获得所求问题的解。
注意: 在编写递归函数时需要注意,函数中定义的局部变量和形
式参数只在当前的调用层有效,当回推到简单问题时,原来调用层中
的局部变量和参数都被隐藏起来。每一个简单问题层中都有自己的局
部变量和参数。