三个整数序列的最长公共子序列

时间:2016-06-05 08:50:56

标签: python dynamic-programming

我已经看到了类似的答案,但并不特定于我正在使用的方法类型。我试图找到三个整数序列中最长的公共子序列。在这种情况下,a = [8,3,2,1,7] b = [8,2,1,3,8,10,7] c = [6,8,3,1,4,7]和输出应该是3,其中最长的公共子序列是[8,3,7]或[8,1,7]。我的代码输出序列共有的整数,但不是它们共有的“序列”,该序列的长度和三个序列的“编辑距离”,它与公共整数的长度相同。我使用了编辑距离算法的修改并对其进行了修改以应对第三个序列。我需要修改它以产生公共序列而不仅仅是公共整数。任何帮助将不胜感激!

def lcs3(a, b, c):


        n = len(a)
        m = len(b)
        l = len(c)

        E = [[[0 for k in range(l+1)] for j in range(m+1)] for i in range(n+1)]

        common = []

        for i in range(1,n+1):
            E[i][0][0] = i

        for j in range(1,m+1):
            E[0][j][0] = j

        for k in range(1,l+1):
            E[0][0][k] = k    


        for j in range(1,m+1):
            for i in range(1,n+1):
                for k in range(1,l+1):
                    #insertion between first and 2nd sequence
                    insertionij = E[i][j-1][k] + 1

                    #insertion between 2nd and 3rd sequence
                    insertionjk = E[i][j][k-1] + 1

                    #deletion between 1st and 2nd sequence
                    deletionij = E[i-1][j][k] + 1

                    #deletion between 2nd and 3rd sequence
                    deletionjk = E[i][j-1][k] + 1

                    #matches and mismatches between 1st through to 3rd sequences
                    matchijk = E[i-1][j-1][j-1]
                    mismatchijk = E[i-1][j-1][k-1] + 1

                    if a[i-1] == b[j-1] == c[k-1]:
                        E[i][j][k] = min(insertionij, insertionjk, deletionij, deletionjk, matchijk)

                        common.append(a[i-1])

                    else:
                        E[i][j][k] = min(insertionij, insertionjk, deletionij, deletionjk, mismatchijk)

        common = list(set(common))
        #print(E)
        return (E[n][m][l], len(common), common)

1 个答案:

答案 0 :(得分:0)

这与我们如何解决两个数组上的lcs问题非常相似。

def lcs3(a, b, c):
    n = len(a)
    m = len(b)
    l = len(c)

    if 0 in (n, m, l):
        return 0

    E = [[[0] * (l + 1) for _ in range(m + 1)] for _ in range(n + 1)]

    for i in reversed(range(n + 1)):
        for j in reversed(range(m + 1)):
            for k in reversed(range(l + 1)):
                if i == n or j == m or k ==l:
                    E[i][j][k] = 0
                elif a[i] == b[j] == c[k]:
                    E[i][j][k] = 1 + E[i + 1][j + 1][k + 1]
                else:
                    E[i][j][k] = max(E[i + 1][j][k], E[i][j + 1][k], E[i][j][k + 1])

    return E[0][0][0]