美文网首页
最小编辑距离

最小编辑距离

作者: 以梦为马驾驾驾 | 来源:发表于2022-04-04 20:20 被阅读0次

    最小编辑距离

    编辑距离有两种:

    1. Levenshtein距离: 允许插入,删除和替换一个字符, 最常见
    2. Damerau-Levenshtein距离: 在上者的基础上, 允许交换相邻两字符的位置, 在git中使用
      另外, 操作的权重不同可以分为: 非加权, 和 加权

    应用场景:

    • DNA 序列的比对 (两段DNA, 如果编辑距离很小, 说明可能是同源DNA发生了一点突变)
    • 拼写检查, 最接地气的了

    LeetCode上第72题(72. 编辑距离 - 力扣(LeetCode) (leetcode-cn.com))

    另外CS61a中在作业cat 里也要求实现最小编辑距离

    一般两种做法:

    1. 递归( 自顶向下, 会有很多的重复计算, 不过可以采用memo, 但是效果应该还不是很好)
    2. 动规( 自底向上, 采用memo)

    string1和string2 都可以插入, 删除, 和替换一个字符, 可以等价为对:

    • string1 插入一个字符
    • string2 插入一个字符 (删除string1的一个字符)
    • 修改string1中的一个字符

    且在基础的levenshtein编辑距离中, 三种操作的代价是相同的, 实际上, 他们的代价可以是不同的, 这就是加权编辑距离(可能更符合实际场景), 算法实现, 就是在状态转变的时候加上对应的代价.

    动规的一点解释: 二维数组res, res(i)(j), 代表 string1 的前 i 个字符要转化 到 string2 的前 j 个字符需要的编辑距离

    另外: 并没有作业要求记录编辑路径, 可以作为拓展作业.

    def minimum_mewtations(start, goal, limit):
        """A diff function that computes the edit distance from START to GOAL.
        This function takes in a string START, a string GOAL, and a number LIMIT.
    
        Arguments:
            start: a starting word
            goal: a goal word
            limit: a number representing an upper bound on the number of edits
    
        >>> big_limit = 10
        >>> minimum_mewtations("cats", "scat", big_limit)       # cats -> scats -> scat
        2
        >>> minimum_mewtations("purng", "purring", big_limit)   # purng -> purrng -> purring
        2
        >>> minimum_mewtations("ckiteus", "kittens", big_limit) # ckiteus -> kiteus -> kitteus -> kittens
        3
        """
        # assert False, 'Remove this line'
        # def1 iter 缺点: 计算次数多,重复计算, 且没办法提前终止
        def iter_func(s, g, limit):
            if len(s) == 0 or len(g) == 0:
                return max(len(s), len(g))
            elif s[-1] == g[-1]:
                return iter_func(s[:-1], g[:-1], limit)
            else:
                return 1 + min(iter_func(s, g[:-1], limit),iter_func(s[:-1], g,limit),iter_func(s[:-1], g[:-1], limit))
        # return iter_func(start, goal, limit)
        # def2 iter 缺点: 计算次数多,重复计算, 可以采用备忘录的方式来记录计算
        def iter_func(s, g, lim):
            if len(s) == 0 or len(g) == 0:
                return max(len(s), len(g))
            elif s[-1] == g[-1]:
                return iter_func(s[:-1], g[:-1], lim)
            elif lim>= limit:
                return limit + 1;
            else:
                return 1 + min(iter_func(s, g[:-1], lim + 1), iter_func(s[:-1], g, lim + 1), iter_func(s[:-1], g[:-1], lim + 1))
        # return iter_func(start, goal, 0)
        # def3 iter 自底向上, 外加memo (自顶向下也可以)
        def down_up(s, g, limit):
            ls = len(s)
            lg = len(g)
            res_array = [[0 for _ in range(lg + 1)] for _ in range(ls + 1)]
            for x in range(1, lg +1):
                res_array[0][x] = x
            for x in range(1, ls + 1):
                res_array[x][0] = x
    
            for i in range(1, ls + 1):
                for j in range(1, lg + 1):
                    if s[i-1] == g[j-1]:
                        res_array[i][j] = res_array[i-1][j-1]
                    else:
                        res_array[i][j] = min(res_array[i-1][j-1] , res_array[i][j-1], res_array[i-1][j]) + 1
            # print(res_array)
            return res_array[-1][-1]
        return down_up(start, goal, limit)
        #todo 记录编辑路径
    
    参考:
    1. https://www.cnblogs.com/arkenstone/p/6196111.html

    相关文章

      网友评论

          本文标题:最小编辑距离

          本文链接:https://www.haomeiwen.com/subject/nrxhsrtx.html