1.斐波那契

什么是斐波那契,斐波那契额就是一个序列的整数的排序,其定义如下;

Fn = Fn-1 + Fn-2 
with F0 = 0 and F1 = 1

也就是,0,1,1,2,3,5,8,13.。。。。

递归实现:

def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)

非递归实现:

def fibi(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a

在这里,我们如果仔细调试,会发现,递归实现,会消耗更多的时间,这里测试如下:

from timeit import Timer
from fibo import fib t1 = Timer("fib(10)","from fibo import fib") for i in range(1,41):
s = "fib(" + str(i) + ")"
t1 = Timer(s,"from fibo import fib")
time1 = t1.timeit(3)
s = "fibi(" + str(i) + ")"
t2 = Timer(s,"from fibo import fibi")
time2 = t2.timeit(3)
print("n=%2d, fib: %8.6f, fibi: %7.6f, percent: %10.2f" % (i, time1, time2, time1/time2))

结果如下;

C:\Python35\python.exe C:\pylearn\bottlelearn\fibnaqie.py
n= 1, fib: 0.000002, fibi: 0.000003, percent: 0.55
n= 2, fib: 0.000002, fibi: 0.000003, percent: 0.73
n= 3, fib: 0.000003, fibi: 0.000003, percent: 1.20
n= 4, fib: 0.000005, fibi: 0.000003, percent: 1.80
n= 5, fib: 0.000007, fibi: 0.000003, percent: 2.45
n= 6, fib: 0.000012, fibi: 0.000004, percent: 3.31
n= 7, fib: 0.000022, fibi: 0.000003, percent: 6.50
n= 8, fib: 0.000030, fibi: 0.000004, percent: 8.38
n= 9, fib: 0.000049, fibi: 0.000003, percent: 14.58
n=10, fib: 0.000078, fibi: 0.000004, percent: 20.07
n=11, fib: 0.000126, fibi: 0.000004, percent: 35.00
n=12, fib: 0.000203, fibi: 0.000004, percent: 52.29
n=13, fib: 0.000330, fibi: 0.000004, percent: 79.20
n=14, fib: 0.000537, fibi: 0.000004, percent: 120.94
n=15, fib: 0.000925, fibi: 0.000005, percent: 196.18
n=16, fib: 0.001693, fibi: 0.000007, percent: 244.16
n=17, fib: 0.007242, fibi: 0.000011, percent: 652.70
n=18, fib: 0.004422, fibi: 0.000007, percent: 637.64
n=19, fib: 0.010322, fibi: 0.000008, percent: 1240.40
n=20, fib: 0.010813, fibi: 0.000007, percent: 1443.78
n=21, fib: 0.025547, fibi: 0.000011, percent: 2246.24
n=22, fib: 0.035421, fibi: 0.000011, percent: 3192.22
n=23, fib: 0.060877, fibi: 0.000008, percent: 7837.86
n=24, fib: 0.090561, fibi: 0.000007, percent: 12091.41
n=25, fib: 0.132058, fibi: 0.000008, percent: 16415.97
n=26, fib: 0.227813, fibi: 0.000008, percent: 29330.54
n=27, fib: 0.557644, fibi: 0.000014, percent: 38659.17
n=28, fib: 0.578976, fibi: 0.000009, percent: 65224.25
n=29, fib: 1.133326, fibi: 0.000008, percent: 140882.03
n=30, fib: 1.454107, fibi: 0.000009, percent: 169095.94
n=31, fib: 2.274395, fibi: 0.000009, percent: 264486.10
n=32, fib: 3.817956, fibi: 0.000009, percent: 430110.09
n=33, fib: 5.923710, fibi: 0.000009, percent: 688859.58
n=34, fib: 9.629423, fibi: 0.000009, percent: 1020986.44
n=35, fib: 15.910085, fibi: 0.000009, percent: 1686911.18
n=36, fib: 26.556680, fibi: 0.000009, percent: 2901071.88
n=37, fib: 43.014073, fibi: 0.000016, percent: 2673506.31

为什么会这样呢?我们思考一下,递归过程的计算数,具体如下;

从树中可以看到,有重复计算的情况,(f(1)就计算了很多次。

在这里,尝试做一个改进,引入一个临时的字典,把计算过的内容做一个保存:

memo = {0:0, 1:1}
def fibm(n):
if not n in memo:
memo[n] = fibm(n-1) + fibm(n-2)
return memo[n]

重新进行时间的测试:

from timeit import Timer
from fibo import fib t1 = Timer("fib(10)","from fibo import fib") for i in range(1,41):
s = "fibm(" + str(i) + ")"
t1 = Timer(s,"from fibo import fibm")
time1 = t1.timeit(3)
s = "fibi(" + str(i) + ")"
t2 = Timer(s,"from fibo import fibi")
time2 = t2.timeit(3)
print("n=%2d, fib: %8.6f, fibi: %7.6f, percent: %10.2f" % (i, time1, time2, time1/time2))
n= 1, fib: 0.000011, fibi:  0.000015, percent:       0.73
n= 2, fib: 0.000011, fibi: 0.000013, percent: 0.85
n= 3, fib: 0.000012, fibi: 0.000014, percent: 0.86
n= 4, fib: 0.000012, fibi: 0.000015, percent: 0.79
n= 5, fib: 0.000012, fibi: 0.000016, percent: 0.75
n= 6, fib: 0.000011, fibi: 0.000017, percent: 0.65
n= 7, fib: 0.000012, fibi: 0.000017, percent: 0.72
n= 8, fib: 0.000011, fibi: 0.000018, percent: 0.61
n= 9, fib: 0.000011, fibi: 0.000018, percent: 0.61
n=10, fib: 0.000010, fibi: 0.000020, percent: 0.50
n=11, fib: 0.000011, fibi: 0.000020, percent: 0.55
n=12, fib: 0.000004, fibi: 0.000007, percent: 0.59
n=13, fib: 0.000004, fibi: 0.000007, percent: 0.57
n=14, fib: 0.000004, fibi: 0.000008, percent: 0.52
n=15, fib: 0.000004, fibi: 0.000008, percent: 0.50
n=16, fib: 0.000003, fibi: 0.000008, percent: 0.39
n=17, fib: 0.000004, fibi: 0.000009, percent: 0.45
n=18, fib: 0.000004, fibi: 0.000009, percent: 0.45
n=19, fib: 0.000004, fibi: 0.000009, percent: 0.45
n=20, fib: 0.000003, fibi: 0.000010, percent: 0.29
n=21, fib: 0.000004, fibi: 0.000009, percent: 0.45
n=22, fib: 0.000004, fibi: 0.000010, percent: 0.40
n=23, fib: 0.000004, fibi: 0.000010, percent: 0.40
n=24, fib: 0.000004, fibi: 0.000011, percent: 0.35
n=25, fib: 0.000004, fibi: 0.000012, percent: 0.33
n=26, fib: 0.000004, fibi: 0.000011, percent: 0.34
n=27, fib: 0.000004, fibi: 0.000011, percent: 0.35
n=28, fib: 0.000004, fibi: 0.000012, percent: 0.32
n=29, fib: 0.000004, fibi: 0.000012, percent: 0.33
n=30, fib: 0.000004, fibi: 0.000013, percent: 0.31
n=31, fib: 0.000004, fibi: 0.000012, percent: 0.34
n=32, fib: 0.000004, fibi: 0.000012, percent: 0.33
n=33, fib: 0.000004, fibi: 0.000013, percent: 0.30
n=34, fib: 0.000004, fibi: 0.000012, percent: 0.34
n=35, fib: 0.000004, fibi: 0.000013, percent: 0.31
n=36, fib: 0.000004, fibi: 0.000013, percent: 0.31
n=37, fib: 0.000004, fibi: 0.000014, percent: 0.29
n=38, fib: 0.000004, fibi: 0.000014, percent: 0.29
n=39, fib: 0.000004, fibi: 0.000013, percent: 0.31
n=40, fib: 0.000004, fibi: 0.000014, percent: 0.29

python的递归算法学习(2):具体实现:斐波那契和其中的陷阱的更多相关文章

  1. Python递归及斐波那契数列

    递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可 ...

  2. 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)

    先科普一下什么叫斐波那契数列,以下内容摘自百度百科: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因意大利数学家列昂纳多·斐波那契(Leonardoda Fibonacci ...

  3. {每日一题}:四种方法实现打印feibo斐波那契数列

    刚开始学Python的时候,记得经常遇到打印斐波那契数列了,今天玩玩使用四种办法打印出斐波那契数列 方法一:使用普通函数 def feibo(n): """ 打印斐波那契 ...

  4. python学习笔记之斐波拉契数列学习

    著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 如果用Python的列表生成式, ...

  5. Python学习之斐波那契数列实现篇

    描述 一个斐波那契序列,F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n>=2),根据n的值,计算斐波那契数F(n),其中0≤n≤1000. 输入 输入 ...

  6. Python学习基础(三)——装饰器,列表生成器,斐波那契数列

    装饰器——闭包 # 装饰器 闭包 ''' 如果一个内部函数对外部(非全局)的变量进行了引用,那么内部函数被认为是闭包 闭包 = 函数块 + 定义时的函数环境 ''' def f(): x = 100 ...

  7. python学习第四十四天斐波那契数列和yield关键词使用

    斐波那契数列是数学中的常见的算法,第一个第二个不算,从第三个开始,每个数的都是前面两个数的和,使用yield关键词把生成的数列保存起来,调用的时候再调用,下面举例说明一下 def fab(max): ...

  8. Python学习笔记_斐波那契数列

    """ 1.生成100项斐波那契数列 2.求第n项斐波那契数列的值是多少 3.给定终止值,生成此前斐波那契数列 """ # 求第n项斐波那契 ...

  9. C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)

    本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...

随机推荐

  1. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目2

    2014-03-20 02:55 题目:从(0, 0)走到(x, y),其中x.y都是非负整数.每次只能向x或y轴的正方向走一格,那么总共有多少种走法.如果有些地方被障碍挡住不能走呢? 解法1:如果没 ...

  2. Pascal小游戏 俄罗斯方块怀旧版

    俄罗斯方块怀旧版(注释版) {$APPTYPE GUI}{$MODE DELPHI}program WinPiece; usesWindows; constAppName = 'WinPiece';p ...

  3. web前端开发总结(未完)

    由于我也是接触前端开发不久,所以呢,自己也会做点小功课,于是,我把前端能够用到的知识稍稍做了下总结,总结的不全面,以后会慢慢完善的! 移动前端开发基础 (总结----待完善)1.移动前端开发:简而言之 ...

  4. 遍历两个自定义列表来实现字典(key:value)

    #自定义key    ${keys}    create list    key1    key2    key3 #自定义value    ${values}    create list    v ...

  5. 孤荷凌寒自学python第七天 列表的复制与序列的基本运算

    孤荷凌寒自学python第七天 列表的复制与序列的基本运算 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) (同步语音:https://www.ximalaya.com/keji/191030 ...

  6. 破解navicat

    每次试用版也真的是烦,注册机试过一次后,又提示注册 果断选择其他方法 官网先下载一个正版 再下patchNavicat.exe 安装完navicat后直接点击patchNavicat 选择navica ...

  7. 团队Alpha版本冲刺(四)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:何家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员:何宇恒 展示组内最新 ...

  8. android系统联系人分组特效实现(2)---字母表快速滚动

    要实现这种功能,只需要在   android系统联系人分组特效实现(1)---分组导航和挤压动画  的基础上再加上一个自定义控件即可完成. 1.新建项目,继续新建一个java类,BladeView,用 ...

  9. favicon.ico generator

    favicon.ico generator https://www.favicon-generator.org/ https://www.favicon.cc/ https://www.favicon ...

  10. 【bzoj3438】小M的作物 网络流最小割

    原文地址:http://www.cnblogs.com/GXZlegend/p/6801522.html 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物 ...