把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

最短编辑距离(Edit Distance)【DP】

概念

编辑距离(最短编辑距离,Edit Distance)又称Levenshtein
Distance,“是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。一般来说,编辑距离越小,两个串的相似度越大。”
——引用自百度

分析

  • 假设用f[i][j]表示将串a[1…i]转换为串b[1…j]所需的最少操作次数(最短距离)
  • 首先是边界:
    ①i==0时,即a为空,那么对应的f[0][j]的值就为j:增加j个字符,使a转化为b
    ②j==0时,即b为空,那么对应的f[i][0]的值就为i:减少i个字符,使a转化为b

  • 然后考虑一般情况(这里是DP思想):我们要得到将a[1..i]经过最少次数的操作就转化为b[1..j],那么我们就必须在此之前以最少次数(假设为k次)的操作,使现在的a和b只需再做一次操作或者不做操作就可以使a[1..i]转化到b[1..j]。而“之前”有三种情况:
    ①将a[1…i]转化为b[1…j-1]
    ②将a[1..i-1]转化为b[1..j]
    ③将a[1…i-1]转化为b[1…j-1]

    第①种情况,只需要在最后将a[j]加上b[1..i]就可以了,总共就需要k+1次操作。
    第②种情况,只需要在最后将a[i]删除,总共需要k+1个操作。
    第③种情况,只需要在最后将a[i]替换为b[j],总共需要k+1个操作。但如果a[i]刚好等于b[j],就不用再替换了,那就只需要k个操作。

  • 为了得到最小值,将以上三种情况的最小值作为f[i][j]的值(我前面不是说了f[i][j]表示串a[1…i]转换为串b[1…j]所需的最少操作次数嘛),最后答案在f[n][m]中。
  • -

实现(只描述算法部分)

  1. 初始化。边界情况,用循环嵌套或两个独立的循环都可以做到。
    初始化长这个样子
    2.循环嵌套遍历f数组,先处理a[i]==b[j]的情况,如不满足,再从三种情况中选择最小的,作为f[i][j]的值。三种情况中,①如果在k个操作里将a[1…i-1]转换为b[1..j],那就可以将a[i]删除,共需k+1个操作,所以是f[i-1][j]+1;②如果在k个操作里将a[1…i]转换为b[1…j-1] ,那就可以加上b[j],共需k+1个操作;③如果我们可以在k个操作里将a[1…i-1]转换为b[1…j-1],那就可以将a[i]转换为b[j],也是共需k+1个操作。(前面已经处理过了a[i]==b[j]的情况)
    3.最后的答案是f[][]最后一个元素的值。

图解

我们拿POJ的一个样例来举例。
刚开始是这样的:

现在来填表,填表规则:比较a[i-1]和b[j-1]的值(-1是因为字符数组是从0开始的,而f[][]是从0初始化的,从1开始填,比如说第一个空是f[1][1],却要比较a[0][0]。),如果相等,其值为其上、左上、左三个元素中的最小值;如果不等,则是三个元素中的最小值+1(如果你懂了填表规则,能填了,说明你已经懂了)
过程如下:

posted @ 2017-07-13 09:49  Starlight_Glimmer  阅读(42)  评论(0编辑  收藏  举报  来源
浏览器标题切换
浏览器标题切换end