最长公共子序列

时间:2021-08-11
本文章向大家介绍最长公共子序列,主要包括最长公共子序列使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

子序列:

一个序列的子序列是该序列删除若干个元素后得到的序列。例如“ACBD"和”BDF“都是”ABCDFEG“的子序列

最长公共子序列:

给定两个序列X,Y,求X和Y长度最长的公共子序列。

例如,”ABBCBDE“  "DBBCDB" 最长子序列为  ”BBCD“

def lcs_lenth(x, y):
    m = len(x)
    n = len(y)
    c = [[0 for _ in range(n+1)] for _ in range(m+1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if x[i-1] == y[j-1]:
                c[i][j] = c[i-1][j-1] + 1
            else:
                c[i][j] = max(c[i][j-1], c[i-1][j])
    return c

def lcs(x, y):
    m = len(x)
    n = len(y)
    c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
    # 1 来自左上方, 2来自上方, 3 来自左方
    b = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
    for i in range(1, m+1):
        for j in range(1, n+1):
            if x[i-1] == y[j-1]:
                c[i][j] = c[i-1][j-1] + 1
                b[i][j] = 1
                # b[i][j] = '↖'
            elif c[i-1][j] > c[i][j-1]:
                c[i][j] = c[i-1][j]
                b[i][j] = 2
                # b[i][j] = '↑'
            else:
                c[i][j] = c[i][j-1]
                b[i][j] = 3
                # b[i][j] = '←'
    return c, b

def lcs_traceback(x, y):
    c, b = lcs(x, y)
    i = len(x)
    j = len(y)
    res = []
    while i>0 and j>0:
        if b[i][j] ==1:
            res.append(x[i-1])
            i -= 1
            j -= 1
        elif b[i][j] == 2:
            i -= 1
        else:
            j -= 1
    return ''.join(reversed(res))


print(lcs_traceback('ABCBDAB', 'BDCABA'))

原文地址:https://www.cnblogs.com/dzwclimber/p/15128548.html