算法导论---学习笔记07
2014-11-28 16:04
176 查看
动态规划求解最长公共子序列(LCS)
首先,子序列和子串是不一样的。子串是连续的,而子序列中的元素组成可以是不连续的,但元素的位置下标一定是递增的。子问题的递归结构
计算最优值
Procedure LCS_LENGTH(X,Y);begin
m:=length[X];
n:=length[Y];
for i:=1 to m do c[i,0]:=0;
for j:=1 to n do c[0,j]:=0;
for i:=1 to m do
for j:=1 to n do
if x[i]=y[j] then
begin
c[i,j]:=c[i-1,j-1]+1;
b[i,j]:="↖";
end
else if c[i-1,j]≥c[i,j-1] then
begin
c[i,j]:=c[i-1,j];
b[i,j]:="↑";
end
else
begin
c[i,j]:=c[i,j-1];
b[i,j]:="←"
end;
return(c,b);
end;
首先从b[m,n]开始,沿着其中的箭头所指的方向在数组b中搜索。
当b[i,j]中遇到"↖"时(意味着xi=yi是LCS的一个元素),表示Xi与Yj的最长公共子序列是由Xi-1与Yj-1的最长公共子序列在尾部加上xi得到的子序列;
当b[i,j]中遇到"↑"时,表示Xi与Yj的最长公共子序列和Xi-1与Yj的最长公共子序列相同;
当b[i,j]中遇到"←"时,表示Xi与Yj的最长公共子序列和Xi与Yj-1的最长公共子序列相同。
这种方法是按照反序来找LCS的每一个元素的。由于每个数组单元的计算耗费Ο(1)时间,算法LCS_LENGTH耗时Ο(mn)。
2.4、构造最长公共子序列
下面的算法LCS(b,X,i,j)实现根据b的内容打印出Xi与Yj的最长公共子序列。通过算法的调用LCS(b,X,length[X],length[Y]),便可打印出序列X和Y的最长公共子序列。Procedure LCS(b,X,i,j);
begin
if i=0 or j=0 then return;
if b[i,j]="↖" then
begin
LCS(b,X,i-1,j-1);
print(x[i]); {打印x[i]}
end
else if b[i,j]="↑" then LCS(b,X,i-1,j)
else LCS(b,X,i,j-1);
end;
在算法LCS中,每一次的递归调用使i或j减1,因此算法的计算时间为O(m+n)。
例如,设所给的两个序列为X=<A,B,C,B,D,A,B>和Y=<B,D,C,A,B,A>。由算法LCS_LENGTH和LCS计算出的结果如下图所示:
相关文章推荐
- 算法导论学习笔记(1,2)
- 学习笔记 07-01-04
- 算法导论学习笔记-第十五章-动态规划
- 《Javascript高级程序设计》(第2版)学习笔记07--关于Math
- 算法导论学习笔记-第8章 线性时间排序
- 算法导论学习笔记-第十九章-二项堆
- 算法导论学习笔记-第7章 快速排序
- 算法导论学习笔记-2
- 算法导论学习笔记-第4章 递归式
- 算法导论学习笔记-第二十一章-用于不相交集合的数据结构
- jQuery学习笔记 07
- 09 12 07 Java学习笔记
- 09 12 07 Java web 学习笔记
- 算法导论学习笔记-第3章 函数的增长
- 算法导论学习笔记-第六章-堆排序
- 学习笔记 07-1-19
- Vray材质学习笔记07——镜子材质
- 算法导论学习笔记(1)插入排序
- 算法导论学习笔记-第十二章-二叉查找树
- 算法导论学习笔记-第5章 概率分析和随机算法