算法设计与分析 实验九 LCS算法

问题

最长公共子序列LCS算法
设X和Z是两个序列,其中X=<x1, x2, …,xm>,Z=< z1, z2,…, zk>
如果存在X的元素构成的按下标严格递增序列< xi1, xi2, …,xik>,使xij=zj,j=1,2,…,k,那么Z是X的子序列,Z含有的元素个数,称为子序列长度。
设定义X和Y是两个序列,如果Z既是X的子序列,也是Y的子序列,则称Z是X和Y的公共子序列。
例如:
X=<A,B,C,B,D,A,B>
Y=<B,D,C,A,B,A>
最长公共子序列为:
<B,C,A,B>
<B,C,B,A>
<B,D,A,B>
对于给定序列X=<x1, x2, …,xm>,Y=< y1, y 2,…, y j>,求X和Y的最长公共子序列。

解析

Xi=<x1, x2, …,xi>
Yj=< y1, y 2,…, y j>
Zk=< z1, z 2,…, z k>
如果Zk是Xi和Yj的最长公共子序列那么存在如下三种情况:
(1)、xi=yj,那么zk= xi=yj,Zk-1是Xi-1和Yj-1的最长公共子序列。
(2)、xi≠yj,zk≠xi,Zk是Xi-1和Yj的最长公共子序列。
(3)、xi≠yj,zk≠yj,Zk是Xi和Yj-1的最长公共子序列。
递推关系:
C[i,j]表示是Xi和Yj的最长公共子序列的长度
i是X长度,j是Y的长度,C[i,j]是Z的长度

在这里插入图片描述
实例:
X=<A,B,D,C,B,A,C>
Y=<B,C,A,D,A,A>
m=0-7
n=0-6

第一步

初始化C[i,j]

i \ j0123456
00000000
10
20
30
40
50
60
70

1、i=1
(1)、j=1,A≠B,X1≠Y1,C[1,1]=max{C[0,1],C[1,0]}=max{0,0}=0,删除x
(2)、j=2,A≠C,X1≠Y2,C[1,2]=max{C[0,2],C[1,1]}=max{0,0}=0,删除x
(3)、j=3,A=A,X1=Y3,C[1,3]=C[0,2]+1=0+1=1,删除x和y
(4)、j=4,A≠D,X1≠Y4,C[1,4]=max{C[0,4],C[1,3]}=max{0,1}=1,删除y
(5)、j=5,A=A,X1=Y5,C[1,5]=C[0,4]+1=0+1=1,删除x和y
(6)、j=6,A=A,X1=Y6,C[1,6]=C[0,5]+1=0+1=1,删除x和y

2、i=2
(1)、j=1,B=B,X2=Y1,C[2,1]=C[1,0]+1=0+1=1,删除x和y
(2)、j=2,B≠C,X2≠Y2,C[2,2]=max{C[1,2],C[2,1]}=max{0,1}=1,删除y
(3)、j=3,B≠A,X2≠Y3,C[2,3]=max{C[1,3],C[2,2]}=max{1,1}=1,删除x
(4)、j=4,B≠D,X2≠Y4,C[2,4]=max{C[1,4],C[2,3]}=max{1,1}=1,删除y
(5)、j=5,B≠A,X2≠Y5,C[2,5]=max{C[1,5],C[2,4]}=max{1,1}=1,删除x
(6)、j=6,B≠A,X2≠Y6,C[2,6]=max{C[1,6],C[2,5]}=max{1,1}=1,删除x

3、i=3
(1)、j=1,D≠B,X3≠Y1,C[3,1]=max{C[2,1],C[3,0]}=max{1,0}=1,删除x
(2)、j=2,D≠C,X3≠Y2,C[3,2]=max{C[2,2],C[3,1]}=max{1,1}=1,删除x
(3)、j=3,D≠A,X3≠Y3,C[3,3]=max{C[2.3],C[3,2]}=max{1,1}=1,删除x
(4)、j=4,D=D,X3=Y4,C[3,4]=C[2,3]+1=2,删除x和y
(5)、j=5,D≠A,X3≠Y5,C[3,5]=max{C[2,5],C[3,4]}=max{1,2}=2,删除y
(6)、j=6,D≠A,X3≠Y6,C[3,6]=max{C[2,6],C[3,5]}=max{1,2}=2,删除y

4、i=4
(1)、j=1,C≠B,X4≠Y1,C[4,1]=max{C[3,1],C[4,0]}=max{1,0}=1,删除x
(2)、j=2,C=C,X4=Y2,C[4,2]=C[3,1]+1=2,删除x和y
(3)、j=3,C≠A,X4≠Y3,C[4,3]=max{C[3,3],C[4,2]}=max{1,2}=2,删除y
(4)、j=4,C≠D,X4≠Y4,C[4,4]=max{C[3,4],C[4,3]}=max{2,2}=2,删除x
(5)、j=5,C≠A,X4≠Y5,C[4,5]=max{C[3,5],C[4,4]}=max{2,2}=2,删除x
(6)、j=6,C≠A,X4≠Y6,C[4,6]=max{C[3,6],C[4,5]}=max{2,2}=2,删除x

5、i=5
(1)、j=1,B=B,X5=Y1,C[5,1]=C[4,0]+1=0+1=1,删除x和y
(2)、j=2,B≠C,X5≠Y2,C[5,2]=max{C[4,2],C[5,1]}=max{2,1}=2,删除x
(3)、j=3,B≠A,X5≠Y3,C[5,3]=max{C[4,3],C[5,2]}=max{2,2}=2,删除x
(4)、j=4,B≠D,X5≠Y4,C[5,4]=max{C[4,4],C[5,3]}=max{2,2}=2,删除x
(5)、j=5,B≠A,X5≠Y5,C[5,5]=max{C[4,5],C[5,4]}=max{2,2}=2,删除x
(6)、j=6,B≠B,X5≠Y6,C[5,6]=max{C[4,6],C[5,5]}=max{2,2}=2,删除x

6、i=6
(1)、j=1,A≠B,X6≠Y1,C[6,1]=max{C[5,1],C[6,0]}=max{1,0}=1,删除x
(2)、j=2,A≠C,X6≠Y2,C[6,2]=max{C[5,2],C[6,1]}=max{2,1}=2,删除x
(3)、j=3,A=A,X6=Y3,C[6,3]=C[5,2]+1=2+1=3,删除x和y
(4)、j=4,A≠D,X6≠Y4,C[6,4]=max{C[5,4],C[6,3]}=max{2,3}=3,删除y
(5)、j=5,A=A,X6=Y5,C[6,5]=C[5,4]+1=2+1=3,删除x和y
(6)、j=6,A=A,X6=Y6,C[6,6]=C[5,5]+1=2+1=3,删除x和y

7、i=7
(1)、j=1,C≠B,X7≠Y1,C[7,1]=max{C[6,1],C[7,0]}=max{1,0}=1,删除x
(2)、j=2,C=C,X7≠Y2,C[7,2]=C[6,1]+1=1+1=2,删除x和y
(3)、j=3,C≠A,X7≠Y3,C[7,3]=max{C[6,3],C[7,2]}=max{3,2}=3,删除x
(4)、j=4,C≠D,X7≠Y4,C[7,4]=max{C[6,4],C[7,3]}=max{3,3}=3,删除x
(5)、j=5,C≠A,X7≠Y5,C[7,5]=max{C[6,5],C[7,4]}=max{3,3}=3,删除x
(6)、j=6,C≠A,X7≠Y6,C[7,6]=max{C[6,6],C[7,5]}=max{3,3}=3,删除x

最终得到C[i,j]

i\j0123456
00000000
100;删除x0;删除x1;删除x和y1;删除y1;删除x和y1;删除x和y
201;删除x和y1;删除y1;删除x1;删除y1;删除x1;删除x
301;删除x1;删除x1;删除x2;删除x和y2;删除y2;删除y
401;删除x2;删除x和y2;删除y2;删除x2;删除x2;删除x
501;删除x2;删除x2;删除x2;删除x2;删除x2;删除x
601;删除x2;删除x3;删除x和y3;删除y3;删除x和y3;删除x和y
701;删除x2;删除x和y3;删除x3;删除x3;删除x3;删除x

第二步

(1)、X=7,Y=6
查表C(7,6)得“3;删除x”
X=<A,B,D,C,D,A,C>
Y=<B,C,A,D,A,A>
=>
X=<A,B,D,C,D,A>
Y=<B,C,A,D,A,A>

(2)、X=6,Y=6
查表C(6,6)得“3;删除x和y”
X=<A,B,D,C,D,A>
Y=<B,C,A,D,A,A>
=>
X=<A,B,D,C,D>
Y=<B,C,A,D,A>
输出A

(3)、X=5,Y=5
查表C(5,5)得“2;删除x”
X=<A,B,D,C,D>
Y=<B,C,A,D,A>
=>
X=<A,B,D,C>
Y=<B,C,A,D,A>

(4)、X=4,Y=5
查表C(4,5)得“2;删除x”
X=<A,B,D,C,>
Y=<B,C,A,D,A>
=>
X=<A,B,D>
Y=<B,C,A,D,A>

(5)、X=3,Y=5
查表C(3,5)得“2;删除y”
X=<A,B,D>
Y=<B,C,A,D,A>
=>
X=<A,B,D >
Y=<B,C,A,D>

(6)、X=3,Y=4
查表C(3,4)得“2;删除x和y”
X=<A,B,D>
Y=<B,C,A,D>
=>
X=<A,B>
Y=<B,C,A>
输出D

(7)、X=2,Y=3
查表C(2,3)得“1;删除x”
X=<A,B>
Y=<B,C,A>
=>
X=<A,>
Y=<B,C,A>

(8)、X=1,Y=3
查表C(1,3)得“1;删除x和y”
X=<A,>
Y=<B,C,A>
=>
X=<>
Y=<B,C>
输出A

(9)、X=0,Y=2
算法结束,输出<A,D,A>

核心代码

//找到最长公共子串的长度
	public static void findMaxLength() {
		//初始化C[i,j]
		for (int i = 0; i < X.length; i++) {
			C[i][0]=0;
		}
		for (int i = 0; i < Y.length; i++) {
			C[0][i]=0;
		}
		// i 问题的规模(长度)
		for (int i = 1; i <= X.length; i++) {
			// j的值不断变化
			for (int j = 1; j <= Y.length; j++) {
				//X和Y的初始下标为0
				if(X[i-1]==Y[j-1]) {
					C[i][j]=C[i-1][j-1]+1;
					B[i][j]="删除x和y";
				}else {
					if(C[i][j-1]>C[i-1][j]) {
						C[i][j]=C[i][j-1];
						B[i][j]="删除y";
					}else {
						C[i][j]=C[i-1][j];
						B[i][j]="删除x";
					}
				}
			}
		}
	}
	
	//输出最长公共子序列
	public static void maxSubsequence(int i,int j) {
		if(i==0||j==0) {
			return ;
		}
		if("删除x和y".equals(B[i][j])) {
			list.add(X[i-1]);
			i--;
			j--;
		}else if("删除x".equals(B[i][j])){
			i--;
		}else if("删除y".equals(B[i][j])) {
			j--;
		}
		maxSubsequence(i, j);
	}

时间复杂度

算法时间复杂度为O(mn)

源码

github源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值