class Stack(object):
def __init__(self,**kwargs):
self.__dict__.update(kwargs)
def __str__(self):
return '|'.join(
['%s:%s'%(k,getattr(self,k))
for k in sorted(self.__dict__)])
__repr__ = __str__ def fab(n):
if n==1 or n==2:
return 1
return fab(n-1) + fab(n-2) def xfab(n):
rst = 0
stack = [Stack(n=n,stage=0)]
while stack:
#print(stack,rst)
crt=stack.pop()
if crt.stage == 0:
if crt.n == 1 or crt.n == 2:
rst = 1
continue
else:
crt.stage = 1
stack.append(crt)
stack.append(Stack(n=crt.n-1,stage=0))
continue
if crt.stage == 1:
crt.adv = rst
crt.stage = 2
stack.append(crt)
stack.append(Stack(n=crt.n-2,stage=0))
continue
if crt.stage == 2:
rst = crt.adv + rst
continue
return rst

虽然loop繁杂多了,但是它有以下好处:

1.不会像递归函数那样栈溢出

2.对递归过程有了更多控制,例如你可以选择广度优先

再如:

#----------递归--------------------------------
def tmove(n,a=0,b=1,c=2):
if n==1:
yield a,c
else:
yield from tmove(n-1,a,c,b)
yield a,c
yield from tmove(n-1,b,a,c) def fmove(n,a=0,b=1,c=2,d=3):
if n==1:
yield a,d
else:
i = int((math.sqrt(1+8*n)-1)/2)
yield from fmove(n-i,a,d,b,c)
yield from tmove(i,a,b,d)
yield from fmove(n-i,c,b,a,d) #----------循环--------------------------------
def xtmove(n,a=0,b=1,c=2):
stack = [Stack(n=n,a=a,b=b,c=c,stage=0)]
while stack:
crt=stack.pop()
if crt.n == 1:
yield crt.a,crt.c
continue
if crt.stage==0:
crt.stage=1
stack.append(crt)
stack.append(Stack(n=crt.n-1,a=crt.a,b=crt.c,c=crt.b,stage=0))
continue
if crt.stage==1:
yield crt.a,crt.c
stack.append(Stack(n=crt.n-1,a=crt.b,b=crt.a,c=crt.c,stage=0)) def xfmove(n,a=0,b=1,c=2,d=3):
stack = [Stack(n=n,a=a,b=b,c=c,d=d,stage=0)]
while stack:
crt=stack.pop()
if crt.n == 1:
yield crt.a,crt.d
continue
i = int((math.sqrt(1+8*crt.n)-1)/2)
if crt.stage==0:
crt.stage=1
stack.append(crt)
stack.append(Stack(n=crt.n-i,a=crt.a,b=crt.d,c=crt.b,d=crt.c,stage=0))
continue
if crt.stage==1:
yield from xtmove(n=i,a=crt.a,b=crt.b,c=crt.d)
stack.append(Stack(n=crt.n-i,a=crt.c,b=crt.b,c=crt.a,d=crt.d,stage=0)) if __name__=='__main__':
for x,y in xfmove(10000000000):
pass
for x,y in fmove(10000000000):
pass

虽然不太清楚实践中会不会出现这种巨大的参数以至于让递归栈溢出,但至少心里有个底了,以后处理复杂问题,先构建递归函数,再写个loop版.

小参数用递归,大参数就用loop.

将树形递归转换为loop的更多相关文章

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

    记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...

  2. 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹

    前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...

  3. 一个貌似比较吊的递归转换为loop--总算成功了.

    class Stack(object): """ A class to hold arguements and state data. """ ...

  4. 不规则递归转换为while,留底

    我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了. from hanoi import * # example tree ...

  5. 递归转手工栈处理的一般式[C语言]

    是任意形式的递归,是化解的一般式. 主题所谓的“递归调用化解为栈处理”,意思是,将递归函数调用化解为“一个由stack_push stack_pop stack_top等函数调用组成的循环式子”.这里 ...

  6. JS 树形结构与数组结构相互转换、在树形结构中查找对象

    总是有很多需求是关于处理树形结构的,所以不得不总结几个常见操作的写法.¯\_(ツ)_/¯ 首先假设有一个树形结构数据如下 var tree=[ { 'id': '1', 'name': '教学素材管理 ...

  7. 用Python递归解决阿拉伯数字转为中文财务数字格式的问题(2)--打开思路的一种方法

    几天前自己写了个将阿拉伯数字转为中文财务数字的程序.用的递归,不幸的是它是树形递归. 虽然实际过程中不太可能出现金额数字大到让Python递归栈溢出,但是始终是一块心病,这玩意终究在理论上是受限制的. ...

  8. 【PHP】php 递归、效率和分析(转)

    递归的定义 递归(http:/en.wikipedia.org/wiki/Recursive)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...

  9. SICP 关于递归迭代的重新理解以及尾递归的引入...

    看了线性的递归和迭代以及树形递归迭代这部分的内容,感觉对递归和迭代又有了新的理解...所以记录一下,也算对这部分内容的总结吧. 首先书中提到的递归与迭代和我以前想的有点不一样,我感觉书中提到的递归和迭 ...

随机推荐

  1. Servlet学习笔记

    在这里记录最重要的要点 1,tomcat-->conf-->server.xml里面的东西是什么?(tomcat怎么知道“谁”去处理客户端来的请求?) 最主要的是一个依赖的控制,换句话说什 ...

  2. ASP。net 之view

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Index.aspx.cs&qu ...

  3. SQL Server 2008 R2 未能加载文件或程序集Microsoft.SqlServer.Sqm...

    错误提示:未能加载文件或程序集“Microsoft.SqlServer.Sqm, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8 ...

  4. ASP.NET 中DataGrid item 绑定方法

    <Columns> <asp:TemplateColumn HeaderImageUrl="../../Images/delete.GIF"> <He ...

  5. asp发布至IIS

    最近做的一个任务是使用asp写的,显示的是数据库的报表,但是将报表当前目录发布至IIS后,发现还是运行不了 Set conn = Server.CreateObject("ADODB.Con ...

  6. 微信小程序之页面下拉刷新

    如果需要给单个页面设置下拉刷新功能,不需要写在""window"对象里面,直接在  文件名称.json 里面设置即可 { "enablePullDownRefr ...

  7. Flask-uploads 简单使用

    pip install flask-uploads#先导入次此处需要用到的库: from flask_uploads import UploadSet, IMAGES, configure_uploa ...

  8. 题解 P4512 【【模板】多项式除法】

    题目地址 前言 原理有大佬写了 所以蒟蒻只讲下本题的代码细节 我看懂的大佬博客:博客地址 因为可能知道了大致的步骤还有很多细的地方不理解导致写的时候要花很久并且看到大佬们好像都是用递归写的希望能有帮助 ...

  9. IDEA相关设置

    今天终于放弃了MyEclipse,在使用MyEclipse中的各种心酸就不多说,总结成一句话就是:珍爱生命,远离MyEclipse. 换到IDEA后,安装了IdeaVim插件,支持vim的操作,提高的 ...

  10. ArrayBlockingQueue详解

    转自:https://blog.csdn.net/qq_23359777/article/details/70146778 1.介绍 ArrayBlockingQueue是一个阻塞式的队列,继承自Ab ...