一个貌似比较吊的递归转换为loop--总算成功了.
class Stack(object):
"""
A class to hold arguements and state data.
"""
def __init__(self,**kwargs):
self.__dict__.update(kwargs) def __repr__(self):
extra = "|i:%s"%self.i if hasattr(self,'i') else ''
return "n:%s|stage:%s%s"%(self.n,self.stage,extra) def memory(function):
"""
A decorator to help a no-side-effect function avoid
repeative calculation.
"""
cache = {}
def memofunc(*nkw,**kw):
key=str(nkw)+str(kw)
if key not in cache:
cache[key] = function(*nkw,**kw)
return cache[key]
return memofunc def is_equal(rg,*funclist):
"""
to test whether or not a list of one-arguement functions
have the same output if given same arguement.
"""
for n in rg:
rst=[]
for func in funclist:
rst.append(func(n))
assert len(set(rst))==1 @memory
def hanoi_recur(n):
"""
n -> (i,v)
a recursive function to get the smallest number i
and correspondent value.
"""
if n==1:
return 1,1
psb=[]
for i in range(n-1,0,-1):
_, min_v = hanoi_recur(n-i)
psb_v = 2*min_v+2**i-1
psb.append((i,psb_v))
return min(psb,key=lambda x:x[1]) @memory
def hanoi_loop(n):
"""
The loop version of hanoi_recur.
"""
if n==1:
return 1,1
stack = [Stack(n=n,stage=0,)]
cache={1:1}
while stack:
crt=stack.pop()
if crt.n in cache:
psb_v = 2*cache[crt.n]+2**crt.i-1
crt.prt.psb.append((crt.i,psb_v))
continue
if crt.stage==0:
crt.stage, crt.pgs, crt.psb= 1, 0, []
stack.append(crt)
continue
if crt.stage==1:
if crt.pgs != crt.n - 1:
crt.pgs += 1
stack.append(crt)
chd = Stack(n=crt.pgs, stage=0, i=crt.n-crt.pgs, prt=crt)
stack.append(chd)
else:
crt.stage=2
stack.append(crt)
continue
if crt.stage==2 and hasattr(crt,'prt'):
#hasattr - the last stack doesn't have attribute 'prt',
#so it has to be excluded here.
_, min_v = min(crt.psb,key=lambda x:x[1])
psb_v = 2*min_v + 2**crt.i - 1
crt.prt.psb.append((crt.i,psb_v))
cache[crt.n] = min_v
continue
return min(crt.psb,key=lambda x:x[1]) if __name__=='__main__':
is_equal(range(1,300),hanoi_loop,hanoi_recur)
print('passed test!')
一个貌似比较吊的递归转换为loop--总算成功了.的更多相关文章
- 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹
前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...
- 将树形递归转换为loop
class Stack(object): def __init__(self,**kwargs): self.__dict__.update(kwargs) def __str__(self): re ...
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)
问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...
- 求一个集合S中m个元素的所有排列以及一个数组A的全排列—递归实现版完整代码
说明,本文全文代码均用dart语言实现. 求一个集合S中m个元素的所有排列情况,并打印,非常适合用递归的思路实现.本文给出了两种实现方法,一种是给定的填充排列数组长度是固定的,一种是可变长度的.两种方 ...
- 驳 GarbageMan 的《一个超复杂的简介递归》——对延迟计算的实验和思考
这是一篇因骂战而起的博文,GarbageMan 在该文章回复中不仅对我进行了侮辱,还涉及了我的母校,特写此文用理性的分析和实验予以回击. 在此也劝告 GarbageMan,没什么本事就别在那叫嚣了,还 ...
- 不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了. from hanoi import * # example tree ...
- 在主函数中提示用户输入用户名和密码。另写一方法来判断用户输入是否正确。该方法分别返回一个bool类型的登录结果和和一个string类型的登录信息。如登录成功,返回true及“登录成功”,若登录失败则返回false及“用户名错误”或“密码错误”(使用out参数)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- shell脚本安装python、pip--这种写法是错误的---每一个命令执行完都要判断是否执行成功,否则无法进行下一步
shell脚本安装python.pip--不需要选择安装项目--不管用总报错,必须带上判断符号,while没有这种用法,写在这里为了以后少走弯路,所以不要用下面的执行了 首先把pip-.tgz 安装包 ...
随机推荐
- Bootstrap中关闭第二个模态框时出现的问题和解决办法
Bootstrap中关闭第二个模态框时出现的问题和解决办法 1.关闭第二个模态框时,第一个模态框跟着消失. 解决办法: 第二个模态框的代码不要写在第一个模态框里面,确保两个模态框相对独立; 2.关闭第 ...
- [HNOI 2011]XOR和路径
Description 给定一个无向连通图,其节点编号为 1 到 N,其边的权值为非负整数.试求出一条从 1 号节点到 N 号节点的路径,使得该路径上经过的边的权值的“XOR 和”最大.该路径可以重复 ...
- 洛谷P1446 [HNOI2008]Cards
置换群+dp #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring& ...
- ●BZOJ 1797 [Ahoi2009]Mincut 最小割
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1797 题解: 详细的讲解去看http://hzwer.com/3217.html首先跑一个最 ...
- Mybatis迷你版--QueryObjectFactory
今天在看JDBC4.2新规范,然后无意之间就碰到了这个东西QueryObjectFactory, 市面上orm框架有很多,在这里我就不一一列举了.那么今天我来记录一下QueryObjectFactor ...
- 一日一练-JS toString 和valueOf 方法的联系与区别
子曰:类型转换中toString 和valueOf 的联系与区别分析 首先是看看ES5 的规范是如何进行说明的 在这里有几个基础知识点需要了解一下: [[Class]] [[Class]] 属于Obj ...
- jQuery简单笔记
jQuery 是一个 JavaScript 库,简化了 JavaScript 的编程. 语法:$(selector).action() selector 是字符串,表示HTML元素. 对象 符号 例子 ...
- Logistic Regression 算法向量化实现及心得
Author: 相忠良(Zhong-Liang Xiang) Email: ugoood@163.com Date: Sep. 23st, 2017 根据 Andrew Ng 老师的深度学习课程课后作 ...
- Node.js系列文章:利用console输出日志文件
通常我们在写Node.js程序时,都习惯使用console.log打印日志信息,但这也仅限于控制台输出,有时候我们需要将信息输出到日志文件中,实际上利用console也可以达到这个目的的,今天就来简单 ...
- 项目实战15.2—企业级堡垒机 jumpserver快速入门
必备条件 硬件条件 ① 一台安装好 Jumpserver 系统的可用主机(堡垒机) ② 一台或多台可用的 Linux.Windows资产设备(被管理的资产) 服务条件 (1)coco服务 ① 鉴于心态 ...