简介:编辑距离(Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。一般来说,编辑距离越小,两个串的相似度越大。在机器学习里面一般用word2vec或者神经网络来训练得到单词得相似度。

简单理解:量化两个字符串的相似度。

运用场景:

     一般用于单词拼写检查。

编辑距离 计算

 算法原理:

      比如 求a 和 ab之间得编辑距离。

  a  b
0   (从左空格到空格的操作) 1(从左空格到字符a的操作,新增1个字符) 2(从左空格到字符ab的操作,新增2个字符)
a 1   (从上空格到空格字母a的操作)    

    

图中表格的的数字代表其中的编辑距离。 

  a b
0 1 2
a 1 0(上边的a与当前左边的a相似,所以操作0)  
  a b
0 1 2
a 1 0 1

 

 

红色的1计算公式:

      红色0的最小编辑距离,计算距离来源于以下3个操作:

              1、从上边b 的操作。(从b下面的2开始进行操作)

                            左边为空      上边为ab ,也是就 :   空   >   ab         

                            step1:  往下降一位。表达式左右边都要加一个a  则为   a 空   >  a ab 

                            step2:   a  ab  要与 ab  进行一个比较。

                            step3:   表达式左边需要删除一个a,左右才相等。操作为1。

              2、从左边a的操作。

                          左边字符串   a        上边字符串为  a,

                          往右边移动一位,  左边为   a    右边为 ab  

                          只需要新增一个字符串b,操作为1.

              3、从左上角操作。

                           左边字符  空         上边字符  a,   空 > a

                           往斜角移动一位,只进行一个操作,若对左边字符进行操作的话,则往下移动一位, 相当于 上面  左边的空字符串  往下移动了一位.  左边字符 a 空       右边为 a a,            

                                       

                           此时 aa 与 ab 进行一个比较, 需要替换掉一个a,  操作为1  .

以上为大体思路,当然也可以用递归树来理解:

比如两个字符串 mitcmu 和 mtacnu  的编辑距离:(i,j,edits)

编辑距离 计算

 

                   编辑距离 计算        

 

在递归树中,每个节点代表一个状态,状态包含三个变量 (i, j, edist),其中,edist 表示处理到 a[i] 和 b[j] 时,已经执行编辑操作的次数。

在递归树中,(i, j) 两个变量重复的节点很多,比如 (3, 2) 和 (2, 3)。对于 (i, j) 相同的节点,我们只需要保留 edist 最小的,继续递归处理就可以了,剩下的节点都可以舍弃。所以,状态就从 (i, j, edist) 变成了 (i, j, min_edist),其中 min_edist 表示处理到 a[i] 和 b[j],已经执行的最少编辑次数。
 

 代码:

private char[] a = "mitcmu".toCharArray();
private char[] b = "mtacnu".toCharArray();
private int n = 6;
private int m = 6;
private int minDist = Integer.MAX_VALUE; // 存储结果
// 调用方式 lwstBT(0, 0, 0);
public lwstBT(int i, int j, int edist) {
  if (i == n || j == m) {
    if (i < n) edist += (n-i);
    if (j < m) edist += (m - j);
    if (edist < minDist) minDist = edist;
    return;
  }
  if (a[i] == b[j]) { // 两个字符匹配
    lwstBT(i+1, j+1, edist);
  } else { // 两个字符不匹配
    lwstBT(i + 1, j, edist + 1); // 删除 a[i] 或者 b[j] 前添加一个字符
    lwstBT(i, j + 1, edist + 1); // 删除 b[j] 或者 a[i] 前添加一个字符
    lwstBT(i + 1, j + 1, edist + 1); // 将 a[i] 和 b[j] 替换为相同字符
  }
}
 

 

 

 

     

   

 

 

相关文章:

  • 2022-12-23
  • 2021-08-01
  • 2022-03-03
  • 2022-01-04
  • 2021-09-30
  • 2021-10-01
猜你喜欢
  • 2021-11-06
  • 2021-08-19
  • 2021-11-06
  • 2021-04-25
相关资源
相似解决方案