zoukankan      html  css  js  c++  java
  • 两个字符串的编辑距离学习[转载]

    转自:https://blog.csdn.net/ac540101928/article/details/52786435#commentBox

    1.概念

     字符串的编辑距离,又称为Levenshtein距离,由俄罗斯的数学家Vladimir Levenshtein在1965年提出。是指利用字符操作,把字符串A转换成字符串B所需要的最少操作数。其中,字符操作包括:

    • 删除一个字符     a) Insert a character
    • 插入一个字符     b) Delete a character
    • 修改一个字符     c) Replace a character

     例如对于字符串"if"和"iff",可以通过插入一个'f'或者删除一个'f'来达到目的。

    一般来说,两个字符串的编辑距离越小,则它们越相似。如果两个字符串相等,则它们的编辑距离(为了方便,本文后续出现的“距离”,如果没有特别说明,则默认为“编辑距离”)为0(不需要任何操作)。

    2.问题提出

    给定两个字符串A和B,求字符串A至少经过多少步字符操作变成字符串B。 

    1)首先考虑A串的第一个字符

      假设存在两个字符串A和B,他们的长度分别是lenA和lenB。首先考虑第一个字符,由于他们是一样的,所以只需要计算A[2...lenA]和B[2...lenB]之间的距离即可。那么如果两个字符串的第一个字符不一样怎么办?可以考虑把第一个字符变成一样的(这里假设从A串变成B串):

    修改A串的第一个字符成B串的第一个字符,之后仅需要计算A[2...lenA]和B[2...lenB]的距离即可;
    删除A串的第一个字符,之后仅需要计算A[2...lenA]和B[1...lenB]的距离即可;
    把B串的第一个字符插入到A串的第一个字符之前,之后仅需要计算A[1...lenA]和B[2...lenB]的距离即可。

    2)接下来考虑A串的第i个字符和B串的第j个字符。

      我们这个时候不考虑A的前i-1字符和B串的第j-1个字符。如果A串的第i个字符和B串的第j个字符相等,即A[i]=B[j],则只需要计算A[i+1...lenA]和B[j+1...lenB]之间的距离即可。如果不相等,则:

    修改A串的第i个字符成B串的第j个字符,之后仅需要计算A[i+1...lenA]和B[j+1...lenB]的距离即可;
    删除A串的第i个字符,之后仅需要计算A[i+1...lenA]和B[j...lenB]的距离即可;
    把B串的第j个字符插入到A串的第i个字符之前,之后仅需要计算A[i...lenA]和B[j+1...lenB]的距离即可。
      写到这里,自然会想到用递归求解或者动态规划求解,由于用递归会产生很多重复解,所以用动态规划。

     3.使用动态规划求解

    用edit[i][j]表示A串和B串的编辑距离。edit[i][j]表示A串从第0个字符开始到第i个字符和B串从第0个字符开始到第j个字符,这两个字串的编辑距离。字符串的下标从1开始。

    dis[0][0]表示word1和word2都为空的时候,此时他们的Edit Distance为0。很明显可以得出的,dis[0][j]就是word1为空,word2长度为j的情况,此时他们的Edit Distance为j,也就是从空,添加j个字符转换成word2的最小Edit Distance为j;同理dis[i][0]就是,word1长度为i,word2为空时,word1需要删除i个字符才能转换成空,所以转换成word2的最小Edit Distance为i。

    其中flag:

    edit[i-1][j]+1相当于给word2的最后插入了word1的最后的字符,插入操作使得edit+1,之后计算edit[i-1][j];

    edit[i][j-1]+1相当于将word2的最后字符删除,删除操作edit+1,之后计算edit[i][j-1];

    edit[i-1][j-1]+flag相当于通过将word2的最后一个字符替换为word1的最后一个字符。flag标记替换的有效次数。

    //下标减,表示之前的被匹配上了。

    4.实例分析

    比如要计算cafe和coffee的编辑距离。cafe→caffe→coffe→coffee
    先创建一个5×7的表(cafe长度为4,coffee长度为6)

    首先初始化:

    最终结果:

    附上我的计算过程:

    //其中出现水平或者竖直时可以认为是插入或者删除,这个例子中反推时会出现a和f比较,那么翻译过来就是a换成f,或者是f换成a。

    5.代码实现

     //

  • 相关阅读:
    【欧拉质数筛选法 模版】
    【归并排序 逆序对 模版】
    【 lca倍增模板】
    【LSGDOJ 1333】任务安排 dp
    【NOIP2013】火柴排队
    【USACO Feb 2014】Cow Decathlon
    【USACO08NOV】奶牛混合起来Mixed Up Cows
    【LSGDOJ 1351】关灯
    【USACO】干草金字塔
    【USACO】电子游戏 有条件的背包
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/10066421.html
Copyright © 2011-2022 走看看