- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个程序来计算 Python 中的 Levenshtein 距离。我实现了记忆化,因为我递归地运行算法。我的原始函数在函数本身中实现了内存。这是它的样子:
# Memoization table mapping from a tuple of two strings to their Levenshtein distance
dp = {}
# Levenshtein distance algorithm
def lev(s, t):
# If the strings are 0, return length of other
if not s:
return len(t)
if not t:
return len(s)
# If the last two characters are the same, no cost. Otherwise, cost of 1
if s[-1] is t[-1]:
cost = 0
else:
cost = 1
# Save in dictionary if never calculated before
if not (s[:-1], t) in dp:
dp[(s[:-1], t)] = lev(s[:-1], t)
if not (s, t[:-1]) in dp:
dp[(s, t[:-1])] = lev(s, t[:-1])
if not (s[:-1], t[:-1]) in dp:
dp[(s[:-1], t[:-1])] = lev(s[:-1], t[:-1])
# Returns minimum chars to delete from s, t, and both
return min(dp[(s[:-1], t)] + 1,
dp[(s, t[:-1])] + 1,
dp[(s[:-1], t[:-1])] + cost)
这行得通!但是,我找到了一种方法来内存 using decorators .我尝试将此技术应用到我的算法中:
# Memoization table mapping from a tuple of two strings to their Levenshtein distance
def memoize(func):
memo = {}
def wrap(s, t):
if (s, t) not in memo:
memo[(s, t)] = func(s, t)
return memo[(s, t)]
return wrap
# Levenshtein distance algorithm
@memoize # lev = memoize(lev)
def lev(s, t):
# If the strings are 0, return length of other
if not s:
return len(t)
if not t:
return len(s)
# If the last two characters are the same, no cost. Otherwise, cost of 1
if s[-1] is t[-1]:
cost = 0
else:
cost = 1
# Returns minimum chars to delete from s, t, and both
return min(lev(s[:-1], t) + 1,
lev(s, t[:-1]) + 1,
lev(s[:-1], t[:-1]) + cost)
对我来说,这看起来更清晰,也更容易混淆。我以为这两者在功能上是等价的,但是当我运行带有装饰器的版本时,我惊讶地发现我得到了一个RecursionError: maximum recursion depth exceeded
。
我到底错过了什么?使用装饰器在功能上不等价吗?我尝试通过添加 sys.setrecursionlimit(1500)
进行修复,这很有效,但这是一个 hack,并没有解释为什么两者的功能不同。
注意:我使用一段 lorem ipsum 作为维基百科中 s 和 t 的测试字符串:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour.
我知道对于更长的字符串,我的第一个函数将失败。我只想知道为什么装饰的首先失败。谢谢!
最佳答案
考虑原始代码中发生的堆栈帧(函数调用)。它们看起来像:
lev(s, t)
-> lev(..., ...)
-> lev(..., ...)
-> lev(..., ...)
-> lev(..., ...)
在您的内存版本中,它们显示为:
wraps(s, t)
-> lev(..., ...)
-> wraps(s, t)
-> lev(..., ...)
-> wraps(s, t)
-> lev(..., ...)
-> wraps(s, t)
-> lev(..., ...)
-> wraps(s, t)
-> lev(..., ...)
也就是说,您的堆栈帧将是原来的两倍大,因为每个“调用”实际上调用了两个函数。因此,您将更早地耗尽堆栈帧限制。
关于python - 超出最大递归深度,但仅在使用装饰器时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38624852/
我正在使用python 2.7 当我尝试在其上运行epsilon操作时出现此错误, 这是我的代码 import cv2 import numpy as np img = cv2.imread('img
1 很多程序员对互联网行业中广泛讨论的“35岁危机”表示不满,似乎所有的程序员都有着35岁的职业保质期。然而,随着AI技术的兴起,这场翻天覆地的技术革命正以更加残酷且直接的方式渗透到各行各业。程序员
我有一个包含多个子模块的项目,我想列出每个子模块的相对深度 该项目: main_project submodule1 submodule1\submodule1_1 submo
我有一张彩色图像及其深度图,它们都是由 Kinect 捕获的。我想将它投影到另一个位置(以查看它在另一个视角下的样子)。由于我没有 Kinect 的内在参数(相机参数);我该如何实现? P.S:我正在
给出了这三个网址: 1) https://example.com 2) https://example.com/app 3) https://example.com/app?param=hello 假
这个着色器(最后的代码)使用 raymarching 来渲染程序几何: 但是,在图像(上图)中,背景中的立方体应该部分遮挡粉红色实体;不是因为这个: struct fragmentOutput {
我希望能够在 ThreeJS 中创建一个房间。这是我到目前为止所拥有的: http://jsfiddle.net/7oyq4yqz/ var camera, scene, renderer, geom
我正在尝试通过编写小程序来学习 Haskell...所以我目前正在为简单表达式编写一个词法分析器/解析器。 (是的,我可以使用 Alex/Happy...但我想先学习核心语言)。 我的解析器本质上是一
我想使用像 [parse_ini_file][1] 这样的东西。 例如,我有一个 boot.ini 文件,我将加载该文件以进行进一步的处理: ;database connection sett
我正在使用 Mockito 来测试我的类(class)。我正在尝试使用深度 stub ,因为我没有办法在 Mockito 中的另一个模拟对象中注入(inject) Mock。 class MyServ
我试图在调整设备屏幕大小时重新排列布局,所以我这样做: if(screenOrientation == SCREEN_ORIENTATION_LANDSCAPE) { document
我正在 Ubuntu 上编写一个简单的 OpenGL 程序,它使用顶点数组绘制两个正方形(一个在另一个前面)。由于某种原因,GL_DEPTH_TEST 似乎不起作用。后面的物体出现在前面的物体前面
static FAST_FUNC int fileAction(const char *pathname, struct stat *sb UNUSED_PARAM, void *mo
我有这样的层次结构: namespace MyService{ class IBase { public: virtual ~IBase(){} protected: IPointer
我正在制作一个图片库,需要一些循环类别方面的帮助。下一个深度是图库配置文件中的已知设置,因此这不是关于无限深度循环的问题,而是循环已知深度并输出所有结果的最有效方法。 本质上,我想创建一个 包含系统中
如何以编程方式在树状结构上获取 n 深度迭代器?在根目录中我有 List 每个节点有 Map> n+1 深度。 我已修复 1 个深度: // DEPTH 1 nodeData.forEach(base
我正在构建一个包含大量自定义元素的 Polymer 单页界面。 现在我希望我的元素具有某种主样式,我可以在 index.html 或我的主要内容元素中定义它。可以这样想: index.html
我正在尝试每 25 秒连接到配对的蓝牙设备,通过 AlarmManager 安排,它会触发 WakefulBroadcastReceiver 以启动服务以进行连接。设备进入休眠状态后,前几个小时一切正
假设有一个有默认值的函数: int foo(int x=42); 如果这被其他人这样调用: int bar(int x=42) { return foo(x); } int moo(int x=42)
是否可以使用 Javascript 获取 url 深度(级别)? 如果我有这个网址:www.website.com/site/product/category/item -> depth=4www.w
我是一名优秀的程序员,十分优秀!