📜  编辑距离和LCS(最长公共子序列)(1)

📅  最后修改于: 2023-12-03 15:27:38.423000             🧑  作者: Mango

编辑距离和LCS介绍

在求解两个字符串之间的相似度时,编辑距离和LCS是两个常用的算法。编辑距离是指将一个字符串转换成另一个字符串所需要的最少操作次数,可以用来衡量两个字符串的相似度。而LCS则是指两个字符串最长公共部分的长度。

编辑距离

编辑距离的计算方法是基于动态规划的。

假设有两个字符串A和B,字符串A的长度为m,字符串B的长度为n。我们定义d(i,j)为A的前i个字符和B的前j个字符的编辑距离,则有:

  1. 当i=0时,d(i,j)为j,因为B需要j次插入操作才能变为A;

  2. 当j=0时,d(i,j)为i,因为A需要i次删除操作才能变为B;

  3. 当A[i]=B[j]时,d(i,j) = d(i-1,j-1);

  4. 当A[i]!=B[j]时,d(i,j) = min(d(i-1,j), d(i,j-1), d(i-1,j-1)) + 1。

最终的编辑距离为d(m,n)。

下面是编辑距离的Python实现:

def edit_distance(str1, str2):
    m, n = len(str1), len(str2)
    dp = [[0] * (n+1) for _ in range(m+1)]
    for i in range(m+1):
        dp[i][0] = i
    for j in range(n+1):
        dp[0][j] = j
    
    for i in range(1, m+1):
        for j in range(1, n+1):
            if str1[i-1] == str2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
    
    return dp[m][n]

LCS

LCS的计算方法也是基于动态规划的。

假设有两个字符串A和B,字符串A的长度为m,字符串B的长度为n。我们定义c(i,j)为A的前i个字符和B的前j个字符的LCS长度,则有:

  1. 当i=0或j=0时,c(i,j)为0;

  2. 当A[i]=B[j]时,c(i,j) = c(i-1,j-1) + 1;

  3. 当A[i]!=B[j]时,c(i,j) = max(c(i-1,j), c(i,j-1))。

最终的LCS长度为c(m,n)。

下面是LCS的Python实现:

def LCS(str1, str2):
    m, n = len(str1), len(str2)
    dp = [[0] * (n+1) for _ in range(m+1)]
    
    for i in range(1, m+1):
        for j in range(1, n+1):
            if str1[i-1] == str2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    
    return dp[m][n]
参考链接

[1] 编辑距离 - 维基百科

[2] 最长公共子序列 - 维基百科