编辑距离问题

Posted acodingdg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编辑距离问题相关的知识,希望对你有一定的参考价值。

问题:

https://leetcode-cn.com/problems/edit-distance/

讨论:

这个题我在华为笔试的时候遇到过,直接看懵了。无意中在知乎上发现有人讨论这个题(https://zhuanlan.zhihu.com/p/111409982),稍微弄懂了些皮毛,

所以记录一下。

简单的说一下例子:

有字符串“horse” 和字符串“ros”,问从“horse”转化到“ros”要多少步(包括增加(“hor”>"hors", 增加了一个s),删除("horse"->"hors",删除了一个e),改变("horse"->"horst", 由‘e‘->‘t‘))

 这个一般很难想到要用动态规划来做。那么要务是找到递推公式。

从最基本的情况考虑,也就是""->"",需要的步骤是0,那么从""->"ros"最少的步骤则是3(依次增加[r, o, s])。

从"horse"->""的情况同理,是5(依次删除[h,o,r,s,e])。

设dp[i][j]为"horse"[1..i]转换为"ros"[1..j]

那么考虑一下比较现实的“horse”到"ros":“horse”的第i个字符和“ros”第j个做比较的时候

case 1:

  horse[i+1] == ros[j+1]

那么不需要多余操作,也就说说dp[i][j] == dp[i+1][j+1]

case 2:

  horse[i+1] != ros[j+1]

那么这里的问题就是,如何操作才能让horse[1..i+1] ->ros[1..j+1]了

如题目给出的条件,能够进行的操作有3种,假设实际情况为"hor"->"ro"时出现case 2

1. 增加

也就是说,需要"hor"增加一个字符才能转变成"ro"

如果要计算这次的edit的次数,我们需要知道"hor"->"r"的次数,也就是dp[i+1][j]的值。

原因是,我们需要在"hor"上多加一个字符来使"horo"->"ro","hor"->"r",转换好了以后,再来一个增加操作

2. 删除

这里要让"hor"->"ro"使用删除操作,删除"horse"[i+1]让"hor"->"ro", 那么需要的是"ho"->"ro", 也就是dp[i][j+1]

3. 改变

"hor" -> "ro"使用改操作的时候,需要知道"ho"->"r"的转换需要的操作。

因为是最少的操作数量,所以需要使用min来找到这三种对应的那种操作的数量最小

# word1(horse) to word2(ros)
def edit_distance(word1, word2):
    m = len(word1)
    n = len(word2)
    dp = [[0 for _ in range(n+1)] for _ in range(m+1)]
    for i in range(m+1):
        for j in range(n+1):
            if j == 0:
                dp[i][j] = i # "horse" to ""
            if i == 0:
                dp[i][j] = j # "" to "ros"
    for i in range(1,m+1):
        for j in range(1, n+1):
            if word1[i-1] == word2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                inc = dp[i-1][j] + 1
                update = dp[i-1][j-1] + 1
                delete = dp[i][j-1] + 1
                dp[i][j] = min([inc, update, delete])
    return dp[-1][-1]
if __name__ == "__main__":
    res = edit_distance("horse", "ros")
    print(res)
    

 

以上是关于编辑距离问题的主要内容,如果未能解决你的问题,请参考以下文章

如何减少两行浏览片段之间的距离

VsCode编辑器如何自定义代码片段

编辑距离leetcode

如何在 Django Summernote 中显示编程片段的代码块?

简单的方法来分享/讨论/协作的代码片段?

C#通过编辑距离计算两个字符串的相似度的代码