• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-09-05 10:36 Aet 隐藏边栏 |   抢沙发  0 
文章评分 0 次,平均分 0.0

简述

最长公共子序列算法思想,令 X=< x1,x2,...xm > Y=<y1,y2,...yn> 为两个序列, Z=<z1,z2,...zk>为X和Y的某一个最长公共子序列:

  • 如果 xm=yn,则zk=xm=yn,且Z(k-1)X(m-1)Y(n-1)的一个最长公共子序列
  • 如果 xm != yn, 则如果 zk!=xm,意味着 Z X(m-1)Y的一个最长公共子序列
  • 如果 xm != yn, 则如果 zk!=yn,意味着 ZXmY(n-1)的一个最长公共子序列

总结:
如果目标序列A和目标序列B一样长的情况下,它们的最长公共子序列就是序列A(n-1)与序列B(n-1)这两个最长子序列的公共最长子序列。
如果目标序列A和目标序列B不一样长的情况下:
如果是序列A长一些,可能的情况是A(n-1)和B一样长或者A(n-1)都比B长,这样的情况下,A和B的最长公共子序列就是序列A(n-1)和序列B这两个序列的公共最长子序列。如果是序列B长一些,情况也是一样。

定义

定义c[i,j]XiYj的最长公共子序列长度,则 c[i,j]= 0(若 i=0或j=0) ;c[i-1,j-1]+1 (若i,j>0,且xi=yj)max(c[i,j-1],c[i-1,j])(若x,j>0 且 xi!=yj),通过动态规划方法从底向上计算

复杂度

  • 时间复杂度:O(m*n),空间复杂度O(m*n)

实现

  • begin : 第一个序列的起始迭代器
  • end: 第一个序列的终止迭代器
  • flag_matrix: 标记矩阵
  • seq1_index: 第一个子序列为X[0..seq1_index1](从0计数)
  • seq2_index: 第二个子序列为Y[0..seq1_index2](从0计数)
  • out_begin: 存放最长公共子序列结果的起始迭代器(注意必须是引用类型)(要求输出容器足够大可以存放结果)

在计算最长公共子序列过程中,顺便计算了标记矩阵。定义c[i,j]为Xi和Yj的最长公共子序列长度,则

  • c[i,j]= 0(若 i=0或j=0)
  • c[i,j]=c[i-1,j-1]+1 (若i,j>0,且xi=yj)
  • c[i,j]=max(c[i,j-1],c[i-1,j])(若x,j>0 且 xi!=yj)

其中:flag_matrix表征的是如何从c[i-1,j-1]、c[i,j-1]、c[i-1,j]这三者之一到达c[i,j]。即flag_matrix(i,j)对应的是矩阵:

c[i][j] c[i+1][j]
c[i+1][j] c[i+1][j+1]
  • 如果 xi=yj,则标记flag_matrix[i-1][j-1]11,表示<x1...xi><y1...yj>的最长公共子序列也是<x1...x(i-1)><y1...y(j-1)>的最长公共子序。此时递归至X(i-1)Y(j-1)
  • 如果 xi!=yj,且c[i-1,j]> c[i,j-1]则标记flag_matrix[i-1][j-1] 10,表示<x1...xi><y1...yj>的最长公共子序列也是<x1...x(i-1)><y1...yj>的最长公共子序。此时递归至X(i-1)Yj
  • 如果 xi!=yj,c[i,j-1]> c[i-1,j]则标记flag_matrix[i-1][j-1] 01,表示<x1...xi><y1...yj>的最长公共子序列也是<x1...x><y1...y(j-1)>的最长公共子序。此时递归至XiY(j-1)

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-20
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享