Python:递归输出斐波那契数列

今天学习Python的时候做一道练习题,题目是这样的:

题目 导入

  • 问题
    有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总对数为多少?

  • 分析
    简单的分析了一下,发现这个问题其实就是斐波那契数列问题。
    第一个月兔子对数为1,
    第二个月兔子对数还是1,
    第三个月,开始生小兔子啦,那么总的对数是1+1=2,
    第四个月,老兔子又生了,那么1(最开始的老兔子)+1(第四个月老兔子生的)+1(第三个月老兔子生的)=3
    第五个月,1(1老)+1(第五个月老兔子生)+1(第四个月老兔子生)+1(第三个月老兔子生)+1(第三个月老兔子生的小兔子也生了)=5
    第六个月,1(1老)+1(第六个月老兔子生)+1(第五个月老兔子生)+1(第四个月老兔子生)+1(第三个月老兔子生)+1(第三个月老兔子生的小兔子也生了)+1(第三个月老兔子生的小兔子又生了)+1(第四个月老兔子生的小兔子也生了)=8



    可以发现,每个月的兔子的对数为 1,1,2,3,5,8,13,
    因此,经过一个简单的分析,可以看出来,这道题就是考察的斐波那契数列的。

Python代码实现

这个代码实现的话,应该是有多种实现方法的。

  • 直接输出
def rabbit1(n):
    f1=1
    f2=1
    if (n==1 or n==2):
        return 1
    else:
        for i in range(3,n+1):
            f1,f2=f2,f1+f2
        return f2
  • 递归输出方式一
    这个斐波那契数还可以使用递归进行输出,就是非常直观的递归计算。
def rabbit2(n):
    if (n==1 or n==2):
        return 1
    else:
        return rabbit2(n-1)+rabbit2(n-2)
  • 递归输出方式二
    这种方式是把之前算过的斐波那契数存在字典中,这样的话递归要用的话就直接存取,而不是去重新计算。
def rabbit3(n,rabbits={1:1,2:1}):
    if n in rabbits:
        return rabbits[n]
    res=rabbit3(n-1)+rabbit3(n-2)
    rabbits[n]=res
    return res

三种方式的讨论

对于三种方式而言,都可以直接输出结果来。

print(rabbit1(10))
print(rabbit2(10))
print(rabbit3(10))

输出结果为:

55
55
55

可以看出来,程序是没有错的。
现在 n=36 ,再试一试,
第一种方式结果

14930352
    [Finished in 0.3s]

第二种方式结果为:

14930352
    [Finished in 4.7s]

第三种方式结果为:

14930352
    [Finished in 0.3s]

可以看出来,直接递归貌似结果就差远了。而第二种递归,把之前的数据存起来而不是计算则就要快很多了。
至于第一种方式,是相当快得,当n很大,依旧可以秒算。比如说n=10000,第一种方式可以计算。而第三种方式就不行了,告诉我不能计算了,报错。至于为什么还没有弄明白。

关于使用Python输出斐波那契数列的补充

今天在学习python迭代器和生成器,大致记录一下:
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()
字符串,列表或元组对象都可用于创建迭代器:

#import sys         # 引入 sys 模块

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
flag=True
while True:
    try:
        print (next(it))
    except StopIteration:
        #sys.exit()
        flag=False

利用迭代器代替for循环,进行列表数据的遍历输出。

生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。
以下实例使用 yield 实现斐波那契数列:

def iteration_yield(it):
    flag = True
    # a=0
    while flag:
        try:
            print(next(it), end=" ")
        except StopIteration:
            # sys.exit()
            flag = False
    # print(a)


def fibonacci(n):
    a, b, counter = 0, 1, 0
    while True:
        if counter > n:
            return
        yield a
        a, b = b, a + b
        print('%d,%d' % (a, b))
        counter += 1
f = fibonacci(1000)
iteration_yield(f)

这里写图片描述

更多具体的内容可以从这个地方学习到:

http://www.runoob.com/python3/python3-iterator-generator.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值