Algorithm 如何将Levenshteins编辑距离修改为“计数”;相邻信件交换”;as 1编辑

Algorithm 如何将Levenshteins编辑距离修改为“计数”;相邻信件交换”;as 1编辑,algorithm,string,levenshtein-distance,Algorithm,String,Levenshtein Distance,我在玩,我想把它扩展到计算换位,也就是相邻字母的交换,作为1编辑。未修改的算法统计从另一个字符串到达某个字符串所需的插入、删除或替换。例如,从“KITTEN”到“siting”的编辑距离为3。以下是维基百科的解释: if s[i] = t[j] then d[i, j] := d[i-1, j-1] else if i > 0 and j > 0 and s[i] = t[j - 1] and s[i - 1] = t[j] then d[i, j] := minimum

我在玩,我想把它扩展到计算换位,也就是相邻字母的交换,作为1编辑。未修改的算法统计从另一个字符串到达某个字符串所需的插入、删除或替换。例如,从“KITTEN”到“siting”的编辑距离为3。以下是维基百科的解释:

if s[i] = t[j] then 
  d[i, j] := d[i-1, j-1]
else if i > 0 and j > 0 and s[i] = t[j - 1] and s[i - 1] = t[j] then
  d[i, j] := minimum
             (
               d[i-2, j-2] + 1 // transpose
               d[i-1, j] + 1,  // deletion
               d[i, j-1] + 1,  // insertion
               d[i-1, j-1] + 1 // substitution
             )
else
  d[i, j] := minimum
             (
               d[i-1, j] + 1,  // deletion
               d[i, j-1] + 1,  // insertion
               d[i-1, j-1] + 1 // substitution
             )
  • 小猫→ sitten(将“k”替换为“s”)
  • 坐→ sittin(用“i”替换“e”)
  • 西廷→ 坐着(在末尾插入“g”)
  • 按照相同的方法,从“CHIAR”到“CHAIR”的编辑距离为2:

  • 基尔→ 字符(删除“I”)
  • 煤焦→ 主席(插入“I”)

  • 我想把它算作“1编辑”,因为我只交换两个相邻的字母。我该怎么做呢

    在维基百科的算法中还需要一个例子:

    if s[i] = t[j] then 
      d[i, j] := d[i-1, j-1]
    else if i > 0 and j > 0 and s[i] = t[j - 1] and s[i - 1] = t[j] then
      d[i, j] := minimum
                 (
                   d[i-2, j-2] + 1 // transpose
                   d[i-1, j] + 1,  // deletion
                   d[i, j-1] + 1,  // insertion
                   d[i-1, j-1] + 1 // substitution
                 )
    else
      d[i, j] := minimum
                 (
                   d[i-1, j] + 1,  // deletion
                   d[i, j-1] + 1,  // insertion
                   d[i-1, j-1] + 1 // substitution
                 )
    

    您必须修改更新动态规划表的方式。在最初的算法中,我们考虑两个单词的尾部(或头部),它们的长度最多相差一个。更新是所有这些可能性中的最小值

    如果要修改算法,使两个相邻位置的更改计算为一个,则必须在最多相差两个的尾部(或头部)上计算上述最小值。您可以将其扩展到更大的邻域,但随着该邻域的大小,复杂性将成倍增加

    您可以进一步概括并根据删除、插入或替换的角色分配成本,但必须确保分配给成对编辑的成本低于两次单次编辑的成本,否则两次单次编辑将始终获胜

    让单词为w1和w2

    dist(i,j) = min(
                    dist(i-2,j-2) && w1(i-1,i) == w2(j-1,j) else
                    dist(i-1,j-1) && w1(i) == w2(j) else
                    dist(i,j-1)   + cost(w2(j)),
                    dist(i-1,j)   + cost(w1(i)),
                    dist(i-1,j-1) + cost(w1(i), w2(j)),
                    dist(i, j-2)  + cost(w2(j-1,j)),
                    dist(i-2, j)  + cost(w1(i-1,i)),
                    dist(i-2,j-2) + cost(w1(i-1,i), w2(j-1,j))
                    ) 
    

    我所说的
    &&
    的意思是,只有在满足条件的情况下才应该考虑这些行。

    其他答案是实现最佳字符串对齐算法,我认为这不是您所描述的

    我有一个OSA的java实现,在这里进行了一些优化:

    很久以前,我修改了LED,以考虑键盘上的按键位置(例如,如果您在QWERTY或AZERTY键盘上键入“dpgs”,则我的algo将显示“dogs”比“digs”更接近,因为“o”在“p”旁边,而“I”在两个键之外),但我从未按照您想要的方式修改过它。(顺便说一句,我的修改相对简单,algo保留了它的所有动态编程属性)哇,现在我想回到我的旧SVN备份,找到我的LED修改过的algo,并添加以下内容:)它真的工作吗?:)难以置信!我能说什么呢?它就像一个符咒:-)非常感谢!我的第一个方法是对两个字符串进行单独的传递,并搜索和修复相邻的交换,但是代码很快变得非常难看!与我的解决方案相比,你的解决方案是不可信的,而且你的解决方案也是可行的:- OOPS没有在排版过程中更新我的回答。次要注释,如果最后两个字符相同,则可以后退两步+1+1,你的想法是对的,但我被“尾巴(或头)”弄糊涂了,你代码片段中的前两个案例实际上没有提到成本,这也有点令人困惑。@j_random_hacker感谢你的投票,非常感谢。是的,解释是扭曲的:(。我应该用正向迭代或反向迭代来解释动态规划,而不是两者都解释。不过,为了澄清,前两种情况的成本是0,因为完全匹配。