不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了.
from hanoi import *
# example trees for test...
trees=[]
trees.append(None)
trees.append([1,None,None])
trees.append([1,None,[2,None,None]])
trees.append([1,[3,[4,None,None],None],[600,None,None]])
trees.append([1,[3,[4,None,None],[6,None,None]],[2,[5,None,None],[7,None,None]]])
trees.append([10,[6,[8,None,None],[12,None,None]],[11,None,[15,None,None]]])
trees.append([10,[6,[8,[11,None,[15,None,None]],None],[12,None,None]],[10,[6,[8,None,None],[12,None,None]],[11,None,[15,None,None]]]]) # helper functions to build a valid preorder or inorder list from a tree
def _pre(tree):
if tree:
yield tree[0]
yield from _pre(tree[1])
yield from _pre(tree[2])
def _ino(tree):
if tree:
yield from _ino(tree[1])
yield tree[0]
yield from _ino(tree[2])
def pre(tree):
return list(_pre(tree))
def ino(tree):
return list(_ino(tree)) def make(prd,ind):
if prd and ind:
root = prd[0]
root_pos = ind.index(root)
ind_left= ind[:root_pos]
ind_right = ind[root_pos+1:]
cut = len(ind_left)+1
prd_left = prd[1:cut]
prd_right = prd[cut:]
left = make(prd_left,ind_left)
right = make(prd_right,ind_right)
return [root,left,right] def xmake(prd,ind):
stacks=[Stack(stg=0,prd=prd,ind=ind)]
while stacks:
c = stacks.pop()
if c.stg==0:
c.stg=1
if c.prd and c.ind:
root=c.prd[0]
c.tree_list=[root]
root_pos = c.ind.index(root)
ind_left = c.ind[:root_pos]
cut = len(ind_left)+1
prd_left = c.prd[1:cut]
c.ind_right = c.ind[root_pos+1:]
c.prd_right = c.prd[cut:]
stacks.append(c)
stacks.append(Stack(stg=0,prd=prd_left,ind=ind_left))
else:
res = None
elif c.stg==1:
c.stg=2
c.tree_list.append(res)
stacks.append(c)
stacks.append(Stack(stg=0,prd=c.prd_right,ind=c.ind_right))
elif c.stg==2:
c.tree_list.append(res)
res=c.tree_list
return res def ymake(prd,ind):
stacks=[(0,prd,ind,None,None,None,)]
while stacks:
stg,prd,ind,tree_list,prd_right,ind_right = stacks.pop()
if stg==0:
if prd and ind:
root=prd[0]
tree_list=[root]
root_pos = ind.index(root)
ind_left = ind[:root_pos]
cut = len(ind_left)+1
prd_left = prd[1:cut]
ind_right = ind[root_pos+1:]
prd_right = prd[cut:]
stacks.append((1,None,None,tree_list,prd_right,ind_right,))
stacks.append((0,prd_left,ind_left,None,None,None,))
else:
res = None
elif stg==1:
tree_list.append(res)
stacks.append((2,None,None,tree_list,None,None,))
stacks.append((0,prd_right,ind_right,None,None,None,))
elif stg==2:
tree_list.append(res)
res=tree_list
return res if __name__=='__main__':
for tree in trees:
preorder = pre(tree)
inorder = ino(tree)
compare(1,10000,make,xmake,ymake,prd=preorder,ind=inorder)
时间消耗情况"
>>>
1 groups, 10000 times
make best time: 0.005802598746597618
xmake best time: 0.040378714824230735
ymake best time: 0.010430907850763435
1 groups, 10000 times
make best time: 0.023853132543773928
xmake best time: 0.15266406806261454
ymake best time: 0.06813018108264718
1 groups, 10000 times
make best time: 0.061869156080883114
xmake best time: 0.29423481944120744
ymake best time: 0.14889103182256502
1 groups, 10000 times
make best time: 0.09127643060422885
xmake best time: 0.4971307733591055
ymake best time: 0.22370901906617036
1 groups, 10000 times
make best time: 0.15408382101704765
xmake best time: 0.8039180049905172
ymake best time: 0.37127052922146664
1 groups, 10000 times
make best time: 0.1331591427600083
xmake best time: 0.6996409992152874
ymake best time: 0.32450677483017465
1 groups, 10000 times
make best time: 0.2689833157646033
xmake best time: 1.3633301759510097
ymake best time: 0.6343635807709003
不规则递归转换为while,留底的更多相关文章
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹
前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...
- 将树形递归转换为loop
class Stack(object): def __init__(self,**kwargs): self.__dict__.update(kwargs) def __str__(self): re ...
- 一个貌似比较吊的递归转换为loop--总算成功了.
class Stack(object): """ A class to hold arguements and state data. """ ...
- 数据结构笔记01:编程面试过程中常见的10大算法(java)
以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java的角度看问题,包含下面的这些概念: ...
- JavaScript 开发总结(一)
数据类型:JavaScript定义的数据类型有字符串.数字.布尔.数组.对象.Null.Undefined,但typeof有区分可判别的数据分类是number.string.boolean.objec ...
- python 排序算法
冒泡排序: 一. 冒泡排序的定义 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是重复地进 ...
- Java 算法 概念汇总
编程面试的10大算法概念汇总 以下是在编程面试中排名前10的算法相关的概念,我会通过一些简单的例子来阐述这些概念.由于完全掌握这些概念需要更多的努力,因此这份列表只是作为一个介绍.本文将从Java ...
- 面试10大算法汇总——Java篇
问题导读 1 字符串和数组 2 链表 3 树 4 图 5 排序 6 递归 vs 迭代 7 动态规划 8 位操作 9 概率问题 10 排列组合 11 其他 -- 寻找规律 英文版 以下从Java角度解释 ...
随机推荐
- [LeetCode] Shortest Completing Word 最短完整的单词
Find the minimum length word from a given dictionary words, which has all the letters from the strin ...
- Office 365 应用开发的 .NET Core 模板库
概述 前不久我写过一篇文章拥抱开源,Office 365开发迎来新时代,给大家介绍了Office 365开发的典型场景是如何支持开源平台的:Office 365通过Microsoft Graph,以R ...
- [SDOI 2011]黑白棋
Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...
- SRM 558 SurroundingGame
题意: 给定一个网格,每个网格有选取代价和占据收益.每个点被占据,需要满足以下两个条件至少一个条件:1.被选取 2.邻近方格都被选取(有公共边被称为邻近) 不一定要占据所有方格,求最大收益. 输入 ...
- bzoj3825 NOI2017 游戏
题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行nn 场游戏,每场游戏使用一张地 ...
- [Codeforces Round#417 Div.2]
来自FallDream的博客,未经允许,请勿转载,谢谢. 有毒的一场div2 找了个1300的小号,结果B题题目看错没交 D题题目剧毒 E题差了10秒钟没交上去. 233 ------- A.Sag ...
- C语言程序设计第五次作业--循环结构(1)
(一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增加2℉.计算公式如下: c = 5×(f-3 ...
- 我用 tensorflow 实现的“一个神经聊天模型”:一个基于深度学习的聊天机器人
概述 这个工作尝试重现这个论文的结果 A Neural Conversational Model (aka the Google chatbot). 它使用了循环神经网络(seq2seq 模型)来进行 ...
- Json数组删除
有一个json数组,{'people':[{'name':'jetty','sex':'男'},{'name':'lily','sex':'女'}]} 有一个json:var aa={'name':' ...
- java读取mysql表的注释及字段注释
/** * 读取mysql某数据库下表的注释信息 * * @author xxx */ public class MySQLTableComment { public static Connectio ...