023,递归2 疯狂的兔子

这节课试图了解一下 斐波那契(Fibonacci)数列(黄金分割数列)的递归实现,作为一个例子。

斐波那契(Fibonacci)数列的脑补链接

斐波那契提出一个著名的兔子繁殖问题:

如果一对兔子每月能生一对小兔(一雄一雌),而每对小兔在它出生后的第三个月里,又能开始生一对小兔,假定在不发生死亡的情况下,由一对出生的小兔开始,50个月后会有多少对兔子?

在第一个月时,只有一对小兔子,过了一个月,那对兔子成熟了,在第三个月时便生下一对小兔子,这时有两对兔子。再过多一个月,成熟的兔子再生一对小兔子,而另一对小兔子长大,有三对小兔子。如此推算下去,我们便发现一个规律(表格省略):

由此可知,从第一个月开始以后每个月的兔子总数是:1,1,2,3,5,8,13,21,34,55,89,144,233...。若把上述数列继续写下去,得到的数列便称为斐波那契数列。数列中每个数便是前两个数之和,而数列的最初两个数都是1。

用文字来说,就是费波那契数列由0和1开始,之后的费波那契系数就由之前的两数相加。首几个费波那契系数是(OEIS A000045):

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………

特别指出:0不是第一项,而是第零项。——《维基百科》

斐波那契(Fibonacci)数列的迭代实现:

先用数学函数来定义

f(n) :

当n=1 f(n)=1

当n=2 f(n)=1

当n=3 f(n)=2

当n=4 f(n)=3

推理:n>2时数列可表达为: f(n)=f(n-1) + f(n-2) 

练习:假设我们需要求出经历了20个月后,总共有多少对小兔崽子

普通迭代写法:(实在不会写!!!不知是数学盲还是脑残。。。。)

#知道逻辑但不会写代码,打击太大了。。

def fab(n):
    n1 = 1        #第一个月1
    n2 = 1        #第二个月1
    n3 = 1        #第三个月开始,初始化为1
    
    if n < 1:        #判断如果月份小于一那就没意义了。设置返回一个 -1 的错误,供后面调用
        print('输入有误')
       return -1
    
    while (n-2) > 0:
       n3 = n2 + n1    #从第三个月开始,第三个月等于第二个月和第一个月之和,赋值给n3
       n1 = n2    #那么第一个月就等于现在的第二个月,也就是n2的值重新赋值给第一个月    
        n2 = n3    #同理,第二个月等于现在的第三个月,用n3的值重新赋值给第二个月
        n -= 1    # 重新赋值之后,循环次数-1
        
    return n3    #返回结果

result = fab(20)
if result != -1:
    print(‘总共有%d对小兔崽子诞生’ % result)

个人理解:迭代需要一个初始值,那么这里给了第一个月和第二个月的初始值,第三个月是前两个月相加,那么第三个月也有一个初始值,也就是2,当月份变化时,每一个迭代都会重新赋值,也就是说也有三个初始值,一个是当前月的值n3,一个是当前月-1的值即n2,还一个是当前月-2的值,即n1,那么n3就是最后要求的结果。

递归写法:

QQ图片20140301175625

#Fibonacci数列递归写法:

def fab(n):
#判断n如果小于1返回错误信息
    if n < 1:
        print('输入有误!')
        return - 1
# 如果没有下面这条if件句,程序将陷入死循环,为什么??????
    if n == 1 or n == 2:
        return 1
    else:
        return fab(n-1) + fab(n-2)

result = fab(20)
if result != -1:
    print('总共有%d对小兔子诞生' % result)

#我尝试用
def fab(n):
    return fab(n-1) + fab(n-2)

print(fab(20))

#结果返回一个死循环。
#为什么要加上条件语句?如果单单是判断n<2的话,我赋给函数fab(20),并不小于2,
#脑子实在转不过弯来。求明示!!!!!

递归的中心思想就是 分治思想!一个大问题解决不了,那么可以把大问题分解成若干小问题,把若干小问题解决了,那么大问题也就解决了。

但递归也有其缺陷,比如把上面的20改为35,然后运行它,结果发现,递归算法要等那么一秒钟才算出来,如果用迭代,那么结果就是秒出。所以递归要用在适当的位置适当的时机。

转载于:https://www.cnblogs.com/fishdm/p/3575405.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值