将树形递归转换为loop
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的更多相关文章
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 斯坦福NLP课程 | 第18讲 - 句法分析与树形递归神经网络
作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...
- 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹
前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...
- 一个貌似比较吊的递归转换为loop--总算成功了.
class Stack(object): """ A class to hold arguements and state data. """ ...
- 不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了. from hanoi import * # example tree ...
- 递归转手工栈处理的一般式[C语言]
是任意形式的递归,是化解的一般式. 主题所谓的“递归调用化解为栈处理”,意思是,将递归函数调用化解为“一个由stack_push stack_pop stack_top等函数调用组成的循环式子”.这里 ...
- JS 树形结构与数组结构相互转换、在树形结构中查找对象
总是有很多需求是关于处理树形结构的,所以不得不总结几个常见操作的写法.¯\_(ツ)_/¯ 首先假设有一个树形结构数据如下 var tree=[ { 'id': '1', 'name': '教学素材管理 ...
- 用Python递归解决阿拉伯数字转为中文财务数字格式的问题(2)--打开思路的一种方法
几天前自己写了个将阿拉伯数字转为中文财务数字的程序.用的递归,不幸的是它是树形递归. 虽然实际过程中不太可能出现金额数字大到让Python递归栈溢出,但是始终是一块心病,这玩意终究在理论上是受限制的. ...
- 【PHP】php 递归、效率和分析(转)
递归的定义 递归(http:/en.wikipedia.org/wiki/Recursive)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...
随机推荐
- JavaScript数据结构与算法(二) 队列的实现
TypeScript方式源码 class Queue { items = []; public enqueue(element) { this.items.push(element); } publi ...
- [LeetCode] Design Compressed String Iterator 设计压缩字符串的迭代器
Design and implement a data structure for a compressed string iterator. It should support the follow ...
- webpack构建react项目(一)
前言 下面是我们使用到技术栈: webpack + react + redux + react-router + react-thunk + ES6 + .... 注意事项: 建议使用npm5.X 或 ...
- [SDOI 2009]HH去散步
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...
- Codeforces Round #401 (Div. 2)
和FallDream dalao一起从学长那借了个小号打Div2,他切ABE我做CD,我这里就写下CD题解,剩下的戳这里 AC:All Rank:33 小号Rating:1539+217->17 ...
- poj 1873 凸包+枚举
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6198 Accepted: 1 ...
- 【Toll!Revisited(uva 10537)】
题目来源:蓝皮书P331 ·这道题使得我们更加深刻的去理解Dijkstra! 在做惯了if(dis[u]+w<dis[v])的普通最短路后,这道选择路径方案不是简单的比大小的题横在了 ...
- Mybatis之一级缓存,二级缓存
一级缓存:Mybatis的一级缓存在session上,只要通过session查过的数据,都会放在session上,下一次再查询相同id的数据,都直接冲缓存中取出来,而不用到数据库里去取了. 二级缓存: ...
- Java不走弯路教程(1.环境搭建)
1.环境搭建在开始写第一个Java程序之前,我们需要做一些简单的准备工作. 1.1 还记得DOS吗 我们可以通过图形界面来操作我们的电脑.但作为程序员,你首先需要学会用命令行的方式来操作电脑,因为不是 ...
- List Set Map比较
List按对象进入的顺序保存对象,不做排序或编辑操作. Set对每个对象只接受一次,并使用自己内部的排序方法(通常,你只关心某个元素是否属于Set,而不关心它的顺序–否则应该使用List). Map同 ...