📜  最长的公共序列(1)

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

最长的公共序列

最长的公共序列(Longest Common Subsequence,LCS)是在两个字符串中找到一个最长的公共子序列的问题。公共子序列是指在两个序列中,以相同顺序出现的元素组成的子序列。

例如,字符串 "ABCDGH" 和 "AEDFHR" 的最长公共子序列是 "ADH",长度为 3。

LCS 问题涉及到两个字符串。因此,它是一个二维数组上的动态规划问题。算法通常将二维数组表示为一个表格,每个单元格存储 LCS 的长度。

动态规划

我们可以通过以下步骤来解决 LCS 问题:

1. 初始化: 创建一个二维数组 table[m+1][n+1],其中 m 和 n 是两个字符串的长度(下标从 0 开始),table[i][j] 表示第一个字符串前 i 个字符和第二个字符串前 j 个字符的 LCS 的长度。 对于 i=0 或 j=0,table[i][j] 的值为 0。

2. 填充表格: 遍历字符串中的字符,如果两个字符相等,table[i][j] 的值等于 table[i-1][j-1] 加上 1。否则,table[i][j] 的值等于 Max(table[i-1][j], table[i][j-1])。

3. 最长公共子序列: 从 table[m][n] 开始,向左上角遍历 table 数组,如果当前元素等于 table[i-1][j-1] + 1,则将对应的字符添加到结果字符串中,并向左上角移动。

以下是使用 Python 实现 LCS 算法的代码片段:

def lcs(str1, str2):
    m, n = len(str1), len(str2)
    table = [[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]:
                table[i][j] = table[i-1][j-1] + 1
            else:
                table[i][j] = max(table[i-1][j], table[i][j-1])
    # 回溯并构造 LCS
    i, j = m, n
    result = ''
    while i > 0 and j > 0:
        if str1[i-1] == str2[j-1]:
            result = str1[i-1] + result
            i, j = i-1, j-1
        elif table[i-1][j] > table[i][j-1]:
            i -= 1
        else:
            j -= 1
    return result

以上函数接受两个字符串 str1 和 str2,计算它们的最长公共子序列并返回结果。在实现中,我们在 table[m+1][n+1] 中存储 LCS 的长度,并通过回溯构造最长公共子序列。