|
|
1
4
通常,只有当递归函数 primitive-recursive 这基本上意味着他们在身体里只叫自己一次。函数多次调用自身。这样的函数确实需要一个堆栈。可以使堆栈显式,例如使用列表。使用显式堆栈对算法进行的一种重构是
基本上,您需要使每个局部变量成为堆栈框架的元素;这里的局部变量是x、str(x)和循环的迭代计数器。执行返回值有点困难——如果函数刚刚返回,我选择将res设置为not none。 |
|
|
2
3
“疯狂”是指:
你可以从底部开始——一个粗略的变化是:
这是因为,如果你从一个高数字开始,你必须在到达底部(0)之前重复很长一段时间,所以你的记忆装饰器没有按它应该的方式工作。 通过从底部开始,可以确保每次递归调用都会立即命中结果字典。你可能会使用额外的空间,但不会重复太久。 通过使用循环和堆栈,您可以将任何递归函数转换为迭代函数——本质上是手工运行调用堆栈。参见 this question 或 this quesstion 例如,进行一些讨论。这里可能有一个更优雅的基于循环的解决方案,但它不会跳到我的面前。 |
|
|
3
0
嗯,递归主要是关于能够执行一些代码,而不会丢失以前的上下文及其顺序。特别是,函数帧在递归期间放置并保存到调用堆栈上,因此对递归深度进行了限制,因为堆栈大小是有限的。通过在堆内存上创建状态堆栈,可以手动管理/保存每次递归调用所需的信息,从而“增加”递归深度。通常,可用堆内存量大于堆栈内存量。思考:良好的快速排序实现通过创建一个具有不断变化的状态变量的外部循环(在qs示例中的上/下数组边界和pivot)来消除递归到更大的方面。 在我输入这个代码时,MartinV.Lwis给出了一个很好的答案,关于如何将递归函数转换为循环。 |
|
|
4
0
您可以稍微修改一下递归版本:
这样,您就不会多次检查数字。例如,如果你做111,你不需要看110三次。 我不确定这是否算作是您提出的原始算法的迭代版本,但这里是一个记忆迭代版本:
它首先计算输入x所依赖的一组数字。然后它计算这些数字,从底部开始向X方向移动。 由于对calc-dep的测试,代码非常快。它避免了计算多个依赖项。因此,它可以在400毫秒内完成游戏(10000),而最初的游戏需要——我不知道需要多长时间。很长一段时间。 以下是性能测量:
它相当迅速。 |
|
|
MMedina · 将powershell应用于子文件夹 1 年前 |
|
|
YorSubs · Linux中遍历目录的时间不同方法[关闭] 1 年前 |
|
Romn · 在递归函数中键入元组或元组列表 1 年前 |
|
ABGR · 二叉树的直径——当最长路径不通过根时的失败案例 1 年前 |
|
|
Ack · 尝试迭代JSON数据以匹配用户输入 1 年前 |