Python 实现最长公共子序列LCS

    最长公共子序列是动态规划基本题目,下面按照动态规划基本步骤解出来。可以参考July的教程:十分钟搞定LCS

1.剖析最优解的性质,并刻划其结构特征

序列X共有m个元素,序列Y共有n个元素,如果X[m-1]==Y[n-1],那么X[:m]和Y[:n]的最长公共子序列长度就是X[:m-1]和Y[:n-1]的最长公共子序列长度+1;
如果X[m-1]!=Y[n-1],那么X[:m]和Y[:n]的最长公共子序列长度就是最长的(X[:m-1]和Y[:n]的最长公共子序列长度,X[:m]和Y[:n-1]的最长公共子序列长度)。

2.递归定义


3.以自底向上计算最优值

python代码如下:

def LCS_Len(X,Y):
    m = len(X)
    n = len(Y)
#     C = zeros((m+1,n+1))#记录公共最长子串的矩阵
#     flag = zeros((m+1,n+1)) #记录方向
    C = [[0 for i in range(n+1)] for j in range(m+1)]
    flag = [[0 for i in range(n+1)] for j in range(m+1)]
    for i in arange(m):
        for j in arange(n):
            if X[i]==Y[j]:
                C[i+1][j+1] = C[i][j]+1
                flag[i+1][j+1] = 'ok'
            elif C[i+1][j]>C[i][j+1]:
                C[i+1][j+1] = C[i+1][j]
                flag[i+1][j+1] = 'left'
            else:
                C[i+1][j+1] = C[i][j+1]
                flag[i+1][j+1] ='up'
    return C,flag

def printLCS(flag,X,i,j):
    if i==0 or j==0:
        return
    if flag[i][j]=='ok':
        printLCS(flag,X,i-1,j-1)
        print(X[i-1],end='')
    elif flag[i][j] == 'left':
        printLCS(flag,X,i,j-1)
    else:
        printLCS(flag,X,i-1,j)
        

if __name__ == "__main__":
    X = array(["A","B","C","B","D","A","B"])
    Y = array(["B","D","C","A","B","A"])
    c,flag =  LCS_Len(X,Y)
    for i in c:
        print(i)
    print('')
    for j in flag:
        print(j)
    print('')
    printLCS(flag,X,len(X),len(Y))
    print('')


运行结果输出如下:

[0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 1, 1]
[0, 1, 1, 1, 1, 2, 2]
[0, 1, 1, 2, 2, 2, 2]
[0, 1, 1, 2, 2, 3, 3]
[0, 1, 2, 2, 2, 3, 3]
[0, 1, 2, 2, 3, 3, 4]
[0, 1, 2, 2, 3, 4, 4]

[0, 0, 0, 0, 0, 0, 0]
[0, 'up', 'up', 'up', 'ok', 'left', 'ok']
[0, 'ok', 'left', 'left', 'up', 'ok', 'left']
[0, 'up', 'up', 'ok', 'left', 'up', 'up']
[0, 'ok', 'up', 'up', 'up', 'ok', 'left']
[0, 'up', 'ok', 'up', 'up', 'up', 'up']
[0, 'up', 'up', 'up', 'ok', 'up', 'ok']
[0, 'ok', 'up', 'up', 'up', 'ok', 'up']

BCBA

上图是运行结果,第一个矩阵是计算公共子序列长度的,可以看到最长是4
第二个矩阵是构造这个最优解用的;最后输出一个最优解BCBA
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值