【问题标题】:Levenshtein edit distance PythonLevenshtein 编辑距离 Python
【发布时间】:2016-09-19 19:15:32
【问题描述】:

这段代码返回 2 个术语的 Levenshtein 编辑距离。 我怎样才能做到这一点,以便插入和删除只花费 0.5 而不是 1 ?替换应该仍然花费 1。

def substCost(x,y):
   if x == y: 
      return 0
   else: 
      return 1

def  levenshtein(target, source):
   i = len(target); j = len(source)
   if i == 0:  
      return j
   elif j == 0: 
      return i

   return(min(levenshtein(target[:i-1],source)+1,
          levenshtein(target, source[:j-1])+1,
          levenshtein(target[:i-1], source[:j-1])+substCost(source[j-1],target[i-1])))

【问题讨论】:

  • 请修正您的问题的缩进,目前无法阅读。即便如此,将所有内容放在一条线上也不是惯用的 Python,而且很难回答。
  • 到目前为止你尝试过什么?在请人为您解决此问题之前,您应该发布一个尝试
  • 用另一个元音替换一个元音也需要0.5,还是只是插入和删除比正常便宜?用元音替换非元音怎么样?反之亦然?
  • 不要破坏自己的问题。这是不允许的。

标签: python levenshtein-distance


【解决方案1】:

有两个地方需要说明添加或删除元音的成本降低。它们是函数基本情况中的return jreturn i 行,以及前两个递归调用之后的min 调用中的+1s。

我们需要更改其中的每一个以使用“三元”表达式:0.5 if ch in 'aeiou' else 1,而不是假设添加或删除每个字符的成本为 1

对于基本情况,我们可以将返回值替换为对包含三元表达式的生成器表达式的 sum 调用:

if i == 0:  
    return sum(0.5 if ch in 'aeiou' else 1 for ch in source)
elif j == 0: 
    return sum(0.5 if ch in 'aeiou' else 1 for ch in target)

对于后面的情况,我们可以将 +1 替换为三元表达式本身(使用索引而不是 ch 迭代变量):

return min(levenshtein(target[:i-1],source) + (0.5 if target[-1] in 'aeiou' else 1),
           levenshtein(target, source[:j-1]) + (0.5 if source[-1] in 'aeiou' else 1),
           levenshtein(target[:i-1], source[:j-1])+substCost(source[j-1],target[i-1]))

如果您想概括这一点,您可以将三元表达式移到它自己的函数中,命名为 addCost,然后从 levenshtein 函数中的代码调用它。

【讨论】: