• 记住经典的斐波拉契递归和阶乘递归转换为while规律


    记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路.

    # 斐波拉契--树形递归
    
    def fab(n):
        if n<3:
            return n
        return fab(n-1)+fab(n-2)
    
    def wfab(n):
        stacks=[(0,n,None)]
        while stacks:
            stg,n,value=stacks.pop()
            if stg==0:
                if n<3:
                    res=n
                else:
                    stacks.append((1,n,None))
                    stacks.append((0,n-1,None))
            elif stg==1:
                stacks.append((2,n,res))
                stacks.append((0,n-2,None))
            else:
                res=value+res
        return res            
    
    #阶乘--线性递归
    
    def fac(n):
        if n<1:
            return 1
        return n*fac(n-1)
    
    def wfac(n):
        stacks=[(0,n)]
        while stacks:
            stg,n=stacks.pop()
            if stg==0:
                if n<1:
                    res=1
                else:
                    stacks.append((1,n))
                    stacks.append((0,n-1))
            elif stg==1:
                res=res*n
        return res

    理解了原理,即每出现一次递归调用,先对当前栈做一个记号,再创建一个新栈,对应递归调用.比如,将fab略微改变一下,有更多系数,操作符和递归调用,次序也不是按照n-1,n-2这样来,也能比较容易地模拟出来:

    def fab(n):
        if n<4:
            return n
        return (3*fab(n-3)-2*fab(n-1))*4*fab(n-2)

    仿照上面可转化为:

    def wfab(n):
        stacks=[(0,n,None)]
        while stacks:
            stg,n,value=stacks.pop()
            if stg==0:
                if n<4:
                    res=n
                else:
                    stacks.append((1,n,None))
                    stacks.append((0,n-3,None))
            elif stg==1:
                stacks.append((2,n,3*res))
                stacks.append((0,n-1,None))
            elif stg==2:
                stacks.append((3,n,value-2*res))
                stacks.append((0,n-2,None))
            else:
                res=value*4*res
        return res

     再如:

    arr=[1,5,10,25,50]
    
    def xch(my,ars):
        if my==0:
            return 1
        if my<0 or not ars:
            return 0
        return xch(my,ars[1:])+xch(my-ars[0],ars)


    def xch2(my,ars): stk=[(0,my,ars,None)] res = 0 while stk: stg,my,ars,value = stk.pop() if stg==0: if my==0: res = 1 elif my<0 or not ars: res = 0 else: stk.append((1, my, ars, None)) stk.append((0, my, ars[1:], None)) elif stg==1: stk.append((2, my, ars, res)) stk.append((0, my-ars[0], ars, None)) else: res = res + value return res
  • 相关阅读:
    vue双向数据绑定原理
    vue-router原理
    CSS选择器优化
    静态资源的渲染阻塞
    什么是Base64?Base64的原理是什么?
    OAuth的解释
    AMD与CMD的区别
    AMD的实现
    组件通信的几种方式
    关于istream_iterator<int>(cin)和istream_iterator<int>()的一点分析
  • 原文地址:https://www.cnblogs.com/xiangnan/p/3606573.html
Copyright © 2020-2023  润新知