最近在查阅斐波那契数列时,看到下面的文章,总结得非常好,于是自己上手使用 Python 练习并实现多种求解方法

守望:面试官问你斐波那契数列的时候不要高兴得太早​zhuanlan.zhihu.com

斐波那契数列的定义:

斐波那契数列 又称黄金分割数列,指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........ 这个数列从第3项开始,每一项都等于前两项之和

根据定义递归求解

已知:Fib(0) = 0,Fib(1) = 1
Fib(n) = Fib(n-1) + Fib(n-2)

# 根据定义递归求解
def Fib_definition(n):# 检查输入if check_input(n):if (n <= 1): return nreturn Fib_definition(n - 1) + Fib_definition(n - 2)# 默认返回值else:return -1

递归求解,避免重复计算已经出现过的元素

我们都知道,根据定义递归求解,会存在大量的重复计算,于是我们将已经计算过的值保存在数组里,这样在后续需要计算时可以直接使用已经计算过的值,避免重复计算

# 递归求解,避免重复计算已经出现过的元素
def Fib_definition_notRepeat(n, fib_arr = [0, 1]):if check_input(n):# 检查输入if n < 2: return fib_arr[n]else:# 填充数组for x in range(n):fib_arr.append(-1)# 当求得 fib_arr[n-1] 时,fib_arr[n-2] 已知fib_arr[n] = Fib_definition_notRepeat(n-1, fib_arr) + fib_arr[n-2]return fib_arr[n]else:# 默认返回值return -1

递推求解,从已知元素递推所求元素

根据定义递归求解,我们是根据需要求得的元素一步一步倒推,直到倒推到我们已知的元素 ( 第 0 个,第 1 个 ),属于“反向”计算,那如果“正向”计算,从已知元素递推所求元素呢?

# 递推求解,从已知元素递推所求元素
def Fib_recurrence(n):# 检查输入if check_input(n):if n < 2:return nelse:index = 2fib_index_pre_pre = 0fib_index_pre = 1fib_index = 0while n >= index:fib_index = fib_index_pre_pre + fib_index_prefib_index_pre_pre = fib_index_prefib_index_pre = fib_indexindex += 1return fib_indexelse:# 默认返回值return -1

递推求解,把已求得的元素放入数组中

def Fib_recurrence_arr(n):# 检查输入if check_input(n):if n < 2: return nelse:index = 2fib_arr = [0, 1]while n >= index:fib_arr.append(fib_arr[index-1] + fib_arr[index-2])index += 1return fib_arr[len(fib_arr)-1]else:# 默认返回值return -1

尾递归求解

如果不是很理解尾递归,请参见

什么是尾递归?​www.zhihu.com

# 尾递归求解
def Fib_tail_recursion(n, index, fib_pre_pre, fib_pre):# 检查输入if check_input(n):if n < 2: return nelse:if n >= index:fib_index = fib_pre_pre + fib_prefib_pre_pre = fib_prefib_pre = fib_indexindex += 1return Fib_tail_recursion(n, index, fib_pre_pre, fib_pre)else: return fib_preelse:# 默认返回值return -1

利用矩阵求解,所求元素为

中的 A[0][0], 或
中的 A[0][1]

由于以下式子变形后满足定义

# 两个n阶矩阵相乘
def matrix_multiplication(n, A, B):C = []for line in range(n):line_arr = []for column in range(n):item = 0for i in range(n):item += A[line][i] * B[column][i]line_arr.append(item)C.append(line_arr)return C# 矩阵求解,所求元素为A^{n-1} 中的 A[0][0], 或 A^n 中的 A[0][1]
def Fib_matrix(n):if check_input(n):# 检查输入if n < 2: return nA = [[1, 1], [1, 0]]result = [[1, 0], [0, 1]]matrix_n = 2while n > 0:result = matrix_multiplication(matrix_n, result, A)n -= 1return result[0][1]else:# 默认返回值return -1

矩阵快速幂求解,所求元素为

中的 A[0][0], 或
中的 A[0][1]

利用快速幂算法缩短计算次数

# 两个n阶矩阵相乘
def matrix_multiplication(n, A, B):C = []for line in range(n):line_arr = []for column in range(n):item = 0for i in range(n):item += A[line][i] * B[column][i]line_arr.append(item)C.append(line_arr)return C# 矩阵快速幂求解,所求元素为A^{n-1} 中的 A[0][0], 或 A^n 中的 A[0][1]
def Fib_matrix_power(n):# 检查输入if check_input(n):if n < 2: return nA = [[1, 1], [1, 0]]result = [[1, 0], [0, 1]]matrix_n = 2while n > 0:# 判断最后一位是否为1,即可知奇偶if n & 1:result = matrix_multiplication(matrix_n, result, A)A = matrix_multiplication(matrix_n, A, A)n //= 2# n = n >> 1return result[0][1]else:# 默认返回值return -1

通项公式求解

详细推导过程可参考:

斐波那契数列为什么那么重要,所有关于数学的书几乎都会提到?​www.zhihu.com

# 通项公式求解
import numpy
import math
def Fib_general_formula(n):denominator = math.sqrt(5)return int((numpy.power((1+denominator)/2, n) - numpy.power((1-denominator)/2, n)) / denominator)

利用Python生成器

因为这个不是所有语言都能够使用,所以我放在了最后

# 利用 Python 生成器求解
def Fib_python_generator(n):a, b = 0, 1while n > 0:a, b = b, a + bn -= 1yield a
# 获取生成器的最后一个元素
def get_python_generator_item(n):item = 0for i in Fib_python_generator(n):item = ireturn item

代码参考及下载

https://github.com/boxtsecond/Python-Practice/blob/master/FibonacciNumber.py​github.com

python查询斐波那契数列通项公式_斐波那契数列求解总结(Python版)相关推荐

  1. matlab 帕多瓦数列 通项公式_斐波那契数列的通项公式及证明

    简介 斐波那契数列是指的这样的一个数列,从第3项开始,以后每一项都等于前两项之和.写成递推公式即: \[a_n=a_{n-1}+a_{n-2}(n \ge 3) \] 假设令\(a_1=1,a_2=1 ...

  2. matlab 帕多瓦数列 通项公式_斐波那契数列的通项公式

    摘要:本文将以斐波那契数列为引子,导出一般的二阶常系数线性递归式的求解问题. 所谓斐波那契数列指的是数列:1,1,2,3,5,8,13,21,--.即数列满足递推公式 ,( ),用语言描述就是后一项等 ...

  3. matlab 帕多瓦数列 通项公式_斐波那契数列通项公式的函数图像(复数域)

    文末有动图.实部虚部复平面 MATLAB代码(写得不那么优雅): x = @(t) t; yr = @(t) real( 1/sqrt(5) * (((1+sqrt(5))/2).^t - ((1-s ...

  4. python查询斐波那契数列通项公式_分享一个神奇的操作系统——斐波那契+MACD,每一波都有20%以上的收益!...

    斐波那契数列,又称兔子数列,或者黄金分割数列.指的是这样一个数列: 0.1.1.2.3.5.8.13.21--从第三项起,它的每一项都等于前两项的和. 为什么是兔子数列?我们假设兔子在出生两个月后,就 ...

  5. 用python函数写斐波那契数列通项公式_用python函数写斐波那契数列

    斐波那契数列,又称黄金分割数列.因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为"兔子数列",指的是这样一个数列:1.1.2.3.5.8.13.21.34.--在数学上, ...

  6. 波菲那契数列公式_斐波那契数列为什么那么重要,所有关于数学的书几乎都会提到?...

    一句话先回答问题:因为斐波那契数列在数学和生活以及自然界中都非常有用. 下面我就尽我所能,讲述一下斐波那契数列. 一.起源和定义 斐波那契数列最早被提出是印度数学家Gopala,他在研究箱子包装物件长 ...

  7. java斐波那契数列公式_斐波那契数列(公式)

    求大数前几位的方法 当一个数非常大时,如何求出其前几位呢? 如果是给定一个特定的数,当然可以逐步取出每一位即可.如 a得个位,a/10得百位,a/10/10得千位. 但是,当求x^y的前几位时怎么办呢 ...

  8. 斐波纳契回调线_斐波那契回调线(黄金分割线)全面解析

    一.斐波那契数列 斐波那契数列是指这样一个数列:1.1.2.3.5.8.13.21.34--,这个数列从第三项开始,每一项都等于前两项之和.它的通项公式为F(n)=(1/√5)*{[(1+√5)/2] ...

  9. 斐波纳契回调线_斐波那契回调线(黄金分割线)神级操作-经典

    斐波那契回调线(黄金分割线)神级操作-经典 斐波那契回调线,又称黄金分割线.在交易市场上,大多数的技术指标都具有滞后性,导致交易者在使用时不太好掌握.但是,斐波那契回调线具有提前性,能很好的帮助交易者 ...

最新文章

  1. hdu 4778 Gems Fight! 状压dp
  2. 灰色关联法 —— matlab
  3. vue应用开发过程中在谷歌浏览器遇到的奇葩问题——谷歌插件屏蔽接口请求
  4. 兰州中考计算机考试,宜昌、兰州发布中考新政新消息:增加口语考试,采取人机对话形式...
  5. 为什么说苹果是唯一在乎你隐私的科技公司?
  6. hadoop环境准备-大数据Week5-DAY6-1-hadoop
  7. mysql的txid是什么_mysql-存储引擎
  8. 模块化的ESP8266小电视设计与制作
  9. 英语系大一计算机课程有哪些,英语专业大一学习计划.docx
  10. fatal error: ft2build.h: 没有那个文件或目录
  11. pygame: libpng warning: iCCP: known incorrect sRGB profile 报错
  12. 谷歌浏览器配置微信浏览器_在 Chrome (谷歌浏览器) 中模拟微信内置浏览器
  13. 2019.12.31大一练习赛
  14. TEEOS的实例-在线支付系统
  15. 数据结构——前序线索二叉树及其前序遍历
  16. 我国跨国企业外汇风险管理——以海尔公司为例
  17. 《智慧识人术》读书笔记
  18. openlayers中使用rBush(R树)来存放要素等信息,本文修改了一点其中的rbush源码中的demo,使用canvas画出了insert和delete操作(建立树和删除树中数据)
  19. JAVA SE_part.2
  20. 南邮 OJ 2043 有才华的罗老师

热门文章

  1. java项目如何单元测试_大家java web项目开发做单元测试吗?
  2. php 显示状态,php-fpm status状态配置显示
  3. Redis有序集合详解
  4. 我的第一个SpringBoot项目
  5. Python中的lambda和apply结合使用
  6. 数据结构排序1-冒泡,选择,插入排序
  7. python中的以简单例子解释函数参数、函数定义、函数返回值、函数调用
  8. uni-app和php交互DES加密解密数据
  9. Ubuntu 如何为 XMind 添加快速启动方式和图标
  10. HDU 4027 Can you answer these queries?(线段树/区间不等更新)