python实现斐波那契数列的多种方式

正文共: 3269字 8图 预计阅读时间: 9分钟

每日分享

The great pleasure in life is doing what people say you cannot do.

人生最大的快乐就是做到别人认为你做不到的事情。

小闫语录

当我们鼓起勇气去做一件事情的时候,耳边总是会有这么一个声音『你不适合做。/你肯定不行的。/你做梦呢吧?......』各种各样类似的打击。它们让我们丧失信心,甚至怀疑自己。你要明白,这个世界上最懂你的人,不是朋友,不是亲戚,是你自己!你自己最有发言权。如果认定,请坚持。你要做的,就是做到他们认为你做不到的事情,不是为了向他们证明自己,而是告诉自己『我的人生我做主,我说行,不行也行!』

python实现斐波那契数列的多种方式

斐波那契数列

1,1,2,3,5,8,13,21,34,55,89,144,233,377.....这个数列就是大名鼎鼎的斐波那契数列。它被称为黄金分割数列,在面试中也没少碰到它。巴拉巴拉......假装我介绍了很多,下面直接看干货。

首先我们引入一下时间复杂度这个概念,这个是检验算法所耗时间的长短。检验代码的质量终究还是要看算法的。因为下文中我们需要用时间复杂度衡量一下各算法的效率怎么样,寻找一种最优方法。

上图代表的是大量数据的增加,函数所耗费的时间怎么样。

Element元素 operations 运算,作用 Big-O Complexity Chart 大O表示法时间复杂度图

最简单的实现

a, b= 0, 1
while b < 1000:
    print(b,end=',')
    a, b = b, a+b

这个就是我们在初学python时的一种写法,随着我们学习的深入了解,我们也用到了不同的方法实现。

函数实现

1.递推法

首先忽略我代码中无聊的注释方法,哈哈哈~~~~

##############################
# 使用`递推法`实现斐波那契数列   #
#############################
def fib_next(n):
    first_number = 0
    second_number = 1
    for _ in range(n):
        first_number, second_number = second_number, first_number+second_number
    return first_number

if __name__ == '__main__':
    [print(fib_next(i),end=',') for i in range(1,15)]

据说这种方法的时间复杂度是O(n),从图表中对应查看,可以得知这种方法随着数量的增加,速度会越来越慢越来越慢,显然是不可取的。

2.递归法

##############################
#  使用`递归法`实现斐波那契数列  #
#############################
def fib_recursive(n):
    assert n >= 0, "n must be larger than 0"
    if n <= 1:
        return n
    return fib_recursive(n-1) + fib_recursive(n-2)

if __name__ == '__main__':
    [print(fib_recursive(i),end=',') for i in range(1,15)]

这种写法最简单,相对来说很好理解。但是效率却相当的低......,时间复杂度是O(1.618^n)

3.生成器

##############################
#  使用`生成器`实现斐波那契数列  #
#############################
def fib_generator(max):
    first_number, second_number = 0, 1
    while max > 0:
        first_number, second_number = second_number, first_number+second_number
        max -= 1
        yield first_number

if __name__ == '__main__':
    [print(i,end=',') for i in fib_generator(15)]

使用生成器的方法是一种不错的想法。但是仍然不是最好的。

4.矩阵

在看下面的两种方法之前,我们先来看一下矩阵,这是线性代数里面的一块内容。下面简单的解释一下矩阵乘法:

图中左数第一个矩阵的第一行每个元素和第二个矩阵的这一列每个元素做如下的运算:

2 * 1 + 1 * 0 = 2

得到的2作为第三个矩阵的第一行第一列的元素值。同理:

1 * 1 + 0 * 0 = 1

第三个矩阵的第二行第一列的元素值为1。因此两个矩阵相乘得到第三个矩阵。

4.1第一种方法

############################
#  使用`矩阵`实现斐波那契数列  #
###########################
import numpy
def fib_matrix(n):
    res = pow((numpy.matrix([[1, 1], [1, 0]])), n) * numpy.matrix([[1], [0]])
    return res[0][0]
if __name__ == '__main__':
    [print(int(fib_matrix(i)), end=',') for i in range(10) ]

因为幂运算可以使用二分加速,所以矩阵法的时间复杂度为 O(log n)

4.2第二种方法

##########################
#  使用矩阵计算斐波那契数列  #
#########################
import numpy
def Fibonacci_Matrix_tool(n):
    Matrix = numpy.matrix("1 1;1 0")
    # 返回的是matrix类型
    return pow(Matrix, n)

def Fibonacci_Matrix(n):
    result_list = []
    for i in range(0, n):
        result_list.append(numpy.array(Fibonacci_Matrix_tool(i))[0][0])
    return result_list
# 调用
if __name__ == '__main__':
    a = Fibonacci_Matrix(10)
    print(a)

用科学计算包numpy来实现矩阵法 O(log n)

类实现

1.类

#######################################
#  `类内实现内部魔法方法`实现斐波那契数列   #
######################################
class Fibonacci(object):
    def __init__(self, num):
        self.num = num

    def __iter__(self):
        if self.num < 1:
            return 1
        first_number, second_number = 0, 1
        while self.num > 0:
            first_number, second_number = second_number, first_number + second_number
            self.num -= 1
            yield first_number

    def __next__(self):
        return self.__iter__()

if __name__ == '__main__':
    f = Fibonacci(15)
    [print(i,end=',') for i in f]

参考文献: https://www.cnblogs.com/wj-1314/p/8490822.html https://www.cnblogs.com/panlq/p/9307203.html

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

Django相关知识点回顾

美多商城项目导航帖

项目重要技术点介绍

原文发布于微信公众号 - 小闫笔记(Pythonnote)

原文发表时间:2019-02-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券