所以我之前尝试过这个问题,但我想我对自己所寻找的内容并不是很清楚。我正在制作一个最佳的字符串对齐算法it's really just a dynamic programming problem。所以我决定递归地写它。该计划由两部分组成:
我认为我的编辑距离有效。我得到了与同龄人相同的价值观,似乎没有直接的问题。但是,我很难弄清楚如何恢复匹配,插入和删除的序列以显示对齐。我的问题来自于我有一个递归函数,它至少需要三次递归调用。因此,我最终得到的序列比必要的长,因为每个递归调用都会附加一个“移动”(匹配,插入,删除),这可能不会被使用,因为它不是最便宜的。
这是我的代码:
newseq = []
@memoize
def opt(a, b):
global newseq # Visual Alignment 'move' sequence
gap = 1 # Gap cost
if not a:
return len(b)
if not b:
return len(a)
if a and b:
p1 = a[0] in v # First letters vowells?
p2 = b[0] in v
if a[0] == b[0]: # First letters equal each other?
alpha = 0
elif p1 ^ p2: # Vowel and Consonant?
alpha = 1.2
elif p1 and p2: # Vowel and Vowel?
alpha = 0.5
else: # Consonant and Consonant?
alpha = 0.6
r1 = opt(a[1:], b[1:]) + alpha
r2 = opt(a[1:], b) + gap
r3 = opt(a, b[1:]) + gap
# Reset newseq
newseq = newseq[:-3]
# Takes min of recursive calls, and gives associated 'move'
res = min((r1, 'Match'), # Match
(r2, 'Insertion'), # Insertion
(r3, 'Deletion'), # Deletion
key = lambda x: x[0])
newseq.append(res[1])
return res[0]
所以,是的,我知道我所拥有的不起作用。我的全局newseq
变量当前长度为1,因为我尝试通过删除递归调用期间发生的所有追加来重置它。 如何设置一种方法来记录构成使用此递归算法的最佳对齐的“移动”序列?
编辑:这是我的memoize装饰器功能:
def memoize(f):
cache = {}
def decorated_function(*args):
if args in cache:
return cache[args]
else:
cache[args] = f(*args)
return cache[args]
return decorated_function
答案 0 :(得分:1)
1)通过递归函数传递Stack(或其他集合)作为参数。
2)当你递归地调用自己时,也要将你正在采取的步骤推到堆栈上(例如使用步骤类型的枚举和ints / chars / strings /表示它正在做什么)。
3)当您从2)中的呼叫返回时,弹出堆栈并重复2)。
4)当您有解决方案时,您可以存储与其结果/分数相关联的堆栈。