将树形递归转换为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)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...
随机推荐
- 修改 iOS AppIcon
有一次看到亚马逊的客户端打开后,就提示 icon 改变了,回桌面一看,竟然真的变了.然后就上网搜索是怎么实现的,参照着写了一个小 demo ,权当笔记. 首先,导入图片到项目的中,如下图.不要导入到 ...
- java中抽象类和接口之间的异同点
抽象类 接口 声明方式 abstratc class ClassName interface ClassName 包含内容 构造方法,普通方法,抽象方法.static方法 .变量常量 全局常量.抽 ...
- Docker配置加速器
我们国内使用官方Docker Hub仓库实在是太慢了,很影响效率 使用命令编辑文件: vim /etc/docker/daemon.json 加入下面的数据: docker-cn镜像: { " ...
- [LeetCode] Next Closest Time 下一个最近时间点
Given a time represented in the format "HH:MM", form the next closest time by reusing the ...
- 6.19 noip模拟题(题目及解析转自 hzwer 2014-3-15 NOIP模拟赛)
Problem 1 高级打字机(type.cpp/c/pas) [题目描述] 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序 ...
- 【SPOJ839】Optimal Marks 网络流
You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...
- POJ 3233 (矩阵)
题意:对于矩阵A,求A^1 + ...... + A^k 按照矩阵十大经典题的思路大致做了下. 在k为奇数时: A^( k / 2+1)+ 1) * (A^1 + ....... A^(k/2)) ...
- SPOJ 1812 Longest Common Substring II
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- hdu5634 BestCoder Round #73 (div.1)
Rikka with Phi Accepts: 5 Submissions: 66 Time Limit: 16000/8000 MS (Java/Others) Memory Limit: ...
- LCT模板(BZOJ2631)
用LCT实现路径加,路径乘,断开及加上一条边(保证是树),查询路径和. #include <cstdio> #include <algorithm> #define l(x) ...