编辑距离,扭曲

时间:2017-04-11 04:19:15

标签: string algorithm dynamic-programming

我正在尝试使用动态编程来解决问题,但我遇到了一些麻烦。当我从事动态编程时,我通常会确定一个递归算法,然后从那里开始到我的动态解决方案。这次我遇到了麻烦

问题

假设你有两个字符串:m和n,这样n.length大于m.length,而n不包含字符'#'。您希望将m变为与字符串n相同长度的字符串以最低成本。

成本定义为SUM(Penalty(m [i],n [i])),其中i位于字符串char数组的索引中。

惩罚定义为

private static int penalty(char x,char y) {
    if (x==y) { return 0;}
    else if (y=='#') { return 4;}
    else { return 2;}
}

我能想到的唯一方法如下:

[0]如果m和n的长度相同,则返回m

[1]计算在m

的任何索引处插入#的成本

[2]确定具有最小此类成本的字符串。让那个字符串为m'

[3]再次在m'和n上运行算法。

我认为这甚至不是最优的递归算法,这使我相信我没有在动态算法的正确轨道上。

我已经阅读了使用m.length x n.length矩阵进行正常编辑距离,但我看不出如何轻松地将其转换为适合我的算法。

关于我的递归算法的思考以及我需要采取的步骤来实现动态解决方案?

2 个答案:

答案 0 :(得分:0)

采用你的定义(python):

def penalty(x, y):
    if x == y:
        return 0
    if y == '#':
        return 4
    return 2

def cost(n, m):
    return sum(penalty(a, b) for a, b in zip(n, m))

然后,您可以定义重新分配到m的距离,以便包含每个#的最低费用。

def distance(n, m):
    for _ in range(len(n) - len(m)):
        m = min((m[:i]+'#'+m[i:] for i in range(len(m)+1)), key=lambda s: cost(n, s))
    return m

>>> distance('hello world', 'heloworld')
'he#lo#world'

答案 1 :(得分:0)

我能看到最优性原则在这里工作的唯一方法是,如果你解决了n越来越长的问题。所以动态编程解决方案看起来像这样:

  1. 对于长度为m.length()+1的每个连续子字符串,解决问题,生成新m的提案列表。
  2. 选择与相应子字符串的距离最小的提案作为新的m,然后重复此过程。
  3. 您不需要在此算法中存储除当前最佳解决方案之外的任何内容,当然也不需要存储距离矩阵。在我看来,你也非常接近这个解决方案,你只是错过了'缩小n来获得子问题 -