zoukankan      html  css  js  c++  java
  • 爬楼梯问题,yield学习总结

    问题起源:

    一个人爬楼梯,一步可以迈一级,二级,如果楼梯有N级,要求编写程序,求总共有多少种走法。

    简单的一个递归思想,只要爬到了N-1层,或者爬到N-2层,则认定下一步只有一种走法。所以再去找寻N-1、N-2的前两步。动态规划方程为:f(n) = f(n-1) +f(n-2)

     

    方案1:

    def climb_2(n):  # 速度非常慢
        if n not in [1, 2]:
            return climb_2(n - 1) + climb_2(n - 2)
        else:
            return n

    但是运行下来,会发现,climb_2(3) = 3 这个值早在最开始已经被计算出来了,但是后面的climb_2(4)以及后面所有的递归,都会再去重新计算一下这个取值。当嵌套复杂起来,做了非常多的重复工作,速度很差。

     

    方案2:

    dict_t = {1:1, 2:2}
    def climb_1(n):
        global dict_t
        if n not in dict_t.keys():
            dict_t[n - 1] = climb_1(n - 1)
            dict_t[n - 2] = climb_1(n - 2)
            dict_t[n] = dict_t[n - 1] + dict_t[n - 2]
        return dict_t[n]
     

    这样虽然也是递归嵌套,但是有了全局的dict_t的字典做存储,不会再傻乎乎将climb_2(3) 重新计算,算是一定层面的优化了。但是呢有个缺点:必须依赖函数外的nonlocal或者global变量。

    方案3:

    @functools.lru_cache(3)
    def climb_3(n):
        if n not in [1, 2]:
            return climb_3(n - 1) + climb_3(n - 2)
        else:
            return n

    此种方案也是最近学习functools才发现的,有个lru_cache 可以缓存函数的返回值,思路也同方案2,但是更加优雅、干练,而且也摆脱了nonlocal变量的依赖。但是这里还有个问题没弄明白。cache的大小为啥3就够快,但是2就不够。此处留个问号?

     

    方案4:

    def climb_4(n):
        def inner():
            (a, b) = (1, 2)
            yield a
            yield b
            while 1:
                yield (a + b)
                (a, b) = (b, a + b)
                
        bo = inner()
        for _ in range(n):
            s = next(bo)
        return s

    方案4用到了yield关键词(最近才学明白),也即生成器。yield可以看成是个特殊的return,只是当再次进入这个方法时,会从上会的yield存档处继续。会有变量保存的效果。

    受到这层启发后,编写了上面这个方案,n为1,n为2,设了两道关卡,yield出来个a,yield出来个b。。过了1,2后,就进入了死循环阶段。将a + b生成出去,当再次进入函数时,再将a与b重新继续赋值。整体看起来很不错的一种方案。

     

     

  • 相关阅读:
    kali linux 换国内源
    虚拟机桥接网络上网
    excel 无效引用 所引用的单元格不能位于256列
    sublime python配置运行
    java 环境变量配置(win10)
    Python错误:AssertionError: group argument must be None for now
    python if not
    ubuntu 安装mysql
    python 利用jieba库词频统计
    zxy的猪错误
  • 原文地址:https://www.cnblogs.com/july401/p/11286212.html
Copyright © 2011-2022 走看看