动态规划编辑距离_使用动态规划方法解决编辑距离问题

本文介绍了使用动态规划(DP)解决编辑距离问题的方法。编辑距离是指通过插入、删除和替换字符将一个单词转换为另一个单词所需的最少操作数。通过分析问题的最佳子结构和子问题重叠特性,确定其适合使用DP解决。并通过实例详细解释了DP矩阵的填充过程,展示了从两个单词转换的每一步,并探讨了时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

动态规划编辑距离

使用动态编程(DP)解决问题时出现的第一个问题是如何弄清楚DP是解决问题的一种方法?

因此,我将使用动态编程解决问题,并说明如何解决这一问题。

“明确说明的问题是一半解决的问题。” - 约翰·杜威

让我们讨论使问题解决一半的问题。

给定两个单词word1word2。 找到将word1转换为word2所需的最少操作数。
一个单词允许进行以下3种操作:

  1. 插入一个字符
  2. 删除角色
  3. 替换字符

了解问题:

我们将得到两个单词和三个允许的操作。 我们必须通过执行那些允许的动作将word1转换为word2。 主要任务是找到将word1转换为word2所需的最少操作数。

让我们举例说明一下。

输入: word1 =“意图” word2 =“执行”
输出: 5
说明:
意图->意图(删除“ t”)
inention-> enention(用“ e”替换“ i”)
enention-> exention(用“ x”替换“ n”)
exention-> exection(用“ c”替换“ n”)
执行->执行(插入'u')

动态编程的指示(DP):

我已经谈到了DP 文章。 您可以看一下它,以获取有关DP基本概念的更新。 如果我们看一下DP的定义,有两个要点。

1.最佳子结构
2.重叠的子问题

现在最重要的问题是这些要点是什么意思? 让我们一一介绍。

最佳子结构:可以分解为多个块然后组合起来以获得最佳解决方案的问题称为最佳子结构。 这与递归紧密相关。 因此,总而言之,可以说,如果可以递归解决问题,则该问题具有最佳子结构。

编辑距离问题具有最佳的子结构,导致我们必须根据某个预定义条件一次又一次地执行类似的任务。

子问题重叠:如果可以将问题分解为多个子问题,而该子问题涉及多次解决相同的子问题,则称该问题具有子问题重叠。

我们要解决的问题具有相同的特征。 怎么做!...记住主要任务是将一个单词转换为另一个单词。 如果将其划分为另一个级别,可以说,我们必须将一个字符转换为另一个级别。 现在要将一个突然出现的角色转换成另一个角色,首先,我们需要弄清楚转换先前角色所需的操作数。 我们来看一个适合这种情况的例子。 假设我们有word1 ='ab',word2 ='cd'。 要将a转换为c,首先,我们需要询问是否进行了任何操作,否。 要转换-> c,我们需要执行1个操作。 总共0 + 1 = 1次操作。 现在我们必须将b转换为d。 因此,我们必须执行一个将d替换为b的操作,并且总和为(上一个+当前)1 + 1 =2。在某个地方,我们必须存储前一个操作数以计算当前操作。

因此,我们可以说,无论当前情况如何,我们要做的主要事情是计算先前已发生的操作数。 此指示确认此问题包含重叠的子问题。

由于我们已对问题及其与DP的关系进行了概述,因此让我们通过另一个示例深入研究编码部分

这次,我们还将使用图表来计算操作数。 第一个单词的每个字符都将出现在x轴上。 第二单词字符将放置在y轴上。 我们必须牢记一个特殊情况。 我们可能必须将字符串转换为空字符串,反之亦然。 因此,第一列和第一行将用Phi符号表示。 假设单词1 ='TEA'和单词2 ='COFFEE'。 因此,图表将如下所示。

让我们填写第一列。 第一列表示,如果我们想将单词“ TEA”覆盖为一个空字符串,那么所需的操作数将是多少。 我们将一一计算。 如果要将空单词转换为空单词,则操作数为0。如果要将“ T”转换为空单词,则必须删除“ T”。 因此,动作数变为1。类似地,要将TE转换为空字符串,我们需要执行2个动作。 删除“ T”,然后删除“ E”。 如上所述,要将“ TEA”转换为空字,我们必须执行3个删除操作。 第一行的过程也是如此。 这次我们必须在“咖啡”中隐藏一个空词。 计算完所有步骤后,图表将如下所示:

现在,我们将其进行下一步。 在这里,我们将填充图表的第二行。 与往常一样,第一个任务是将“ T”转换为“ C”。 应当采取1行动。 我们要做的就是用“ C”代替“ T”。 此时此刻,我正在思考一个问题。 我们可以将此值与以前的任何值相关联吗? 目前看来困难。 让我帮助您找到一些可能的路径。 我所看到的,我们可以取其任意一个直接的顶部或左侧的值,也可以从其顶部的顶部,左侧和对角线左侧的值中找到最小值,再加上1(似乎更有效,因为我们必须找到最小值动作数。)。 让我们按照上面讨论的过程完成该行。 到目前为止,我们将看到以下图表。

我们可以在行“ E”和列“ E”表示的单元格之前填充第三行。

行“ E”和列“ E”表示的单元格有特殊情况。 在这里我们可以看到必须将'TE'转换为'COFFE'。要达到'COFF',我们需要执行4个动作。 现在,“ E”与“ E”匹配。 匹配时,我们不需要进行任何操作。 因此,操作数保持为4。让我们对该场景进行另一个猜测。 我们只能看到两个首选选项。 从紧靠左或对角线左单元格中获取任何值。

从以上条件中我们应该选择哪一个似乎并不清楚。 为了更加清楚,让我们继续下一步。 目前,我们的目标是将“ TE”转换为“ COFFEE”。 我们必须采取4个动作来匹配“ COFEE”。 现在我们必须在单词上添加另一个“ E”。 因为“ E”与“ E”匹配。 我们保持先前所做的猜测,我们只能找到一个选择。 取立即对角线左单元格的值。

如果我们继续上述步骤,最终图表将类似于:

我们正在寻找的答案存在于图表的右下角单元格中。 太了不起了。。。我们现在有了解决方案。 让我们总结一下过程,以指出解决该问题所需执行的步骤。

解决问题的步骤:

1.  Define a 2d array(n+1 * m+1). Where n and m respectively holds the the length of word1 and word2.
2.  Assign first row with 0 to m, and first column with 0 to n.
3.  Iterate through each of the cell except row 2 and column 2 to calculate the number of actions.
    1. If both of the characters of a given cell matches, take the immediate diagonal left value to fill that cell.
    2. If the characters do not match, find the minimum from immediate left, top or diagonal left values and add 1 to it.
4.  Return the bottom right most cell value.

我们走了很长的路。 我喜欢和Ruby一起工作。 所以我将在Ruby中解决它。

def min_distance(word1, word2)
    m = word1.length
    n = word2.length
    dp =Array .new(m+ 1 ) { Array .new(n+ 1 , 0 ) }
    for i in 0. .m
        dp[i][ 0 ] = i
    end
    for i in 1. .n
        dp[ 0 ][i] = i
    end
    for i in  0. ..m
        for j in  0. ..n
            if word1[i] == word2[j]
                dp[i + 1 ][j + 1 ] = dp[i][j]
            else 
                dp[i + 1 ][j + 1 ] = [dp[i][j], dp[i][j + 1 ], dp[i + 1 ][j]].min + 1
            end
        end
    end
    dp[m][n]
end

时间复杂度:
该算法的时间复杂度为O(m * n)。 当我们遍历每个单元时。

空间复杂度:
我们将所有值存储在2D数组中。 最初,我们添加了额外的一行和一行来存储空状态的值。 因此,该算法的空间复杂度变为O(n + 1 * m + 1)。

了解更多信息:

1. https://www.geeksforgeeks.org/dynamic-programming /
2. https://leetcode.com/problems/edit-distance/
3. https://en.wikipedia.org/wiki/Dynamic_programming

翻译自: https://hackernoon.com/solving-the-edit-distance-problem-using-the-dynamic-programming-approach-486c32lu

动态规划编辑距离

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值