最长公共子序列问题(最)
最长公共子序列的最优值和最优解

最长公共子序列的最优值和最优解
最长公共子序列问题是求解两个序列中最长的相同子序列的问题。
假设两个序列分别为A和B,其长度分别为m和n。
则最长公共子序列的最优值可以用一个m*n的矩阵c来表示。
矩阵c的第i行第j列表示序列A的前i个元素与序列B的前j个元素的最长公共子序列的长度。
为了求解矩阵c,可以采用动态规划的方法。
具体实现方法如下:
1. 定义一个m*n的矩阵c和一个长度为m的数组b。
2. 通过循环,初始化矩阵c和数组b,使其元素值均为0。
3. 使用两个循环,遍历序列A和B的每个元素,如果元素相同,则将矩阵c的对应位置赋值为左上角元素值加1,并将数组b的对应位置赋值为1;否则将矩阵c的对应位置赋值为左侧和上方元素的较大值。
4. 遍历完序列A和B后,矩阵c的最后一个元素即为两个序列的最长公共子序列的长度。
5. 通过倒序遍历数组b,将序列A中对应元素添加到结果序列中,直至遍历完所有元素。
最终,得到的结果序列即为最长公共子序列的最优解。
在实际应用中,最长公共子序列问题有着广泛的应用,如字符串匹配、生物信息学和版本控制等方面。
最长公共子序列问题

2.3最长公共子序列问题和前面讲的有所区别,这个问题的不涉及走向。
很经典的动态规划问题。
例题16最长公共子序列(lcs.pas/c/cpp)【问题描述】一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
确切地说,若给定序列X= < x1, x2,…, xm>,则另一序列Z= < z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列< i1, i2,…, ik>,使得对于所有j=1,2,…,k有Xij=Zj例如,序列Z=是序列X=的子序列,相应的递增下标序列为<2,3,5,7>。
给定两个序列X 和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例如,若X= < A, B, C, B, D, A, B>和Y= < B, D, C, A, B, A>,则序列是X和Y的一个公共子序列,序列也是X和Y的一个公共子序列。
而且,后者是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。
给定两个序列X= < x1, x2, …, xm>和Y= < y1, y2, … , yn>,要求找出X和Y的一个最长公共子序列。
【输入文件】输入文件共有两行,每行为一个由大写字母构成的长度不超过200的字符串,表示序列X和Y。
【输出文件】输出文件第一行为一个非负整数,表示所求得的最长公共子序列的长度,若不存在公共子序列,则输出文件仅有一行输出一个整数0,否则在输出文件的第二行输出所求得的最长公共子序列(也用一个大写字母组成的字符串表示。
【输入样例】ABCBDABBDCBA【输出样例】4BCBA【问题分析】这个问题也是相当经典的。
这个题目的阶段很不明显,所以初看这个题目没什么头绪,不像前面讲的有很明显的上一步,上一层之类的东西,只是两个字符串而且互相没什么关联。
但仔细分析发现还是有入手点的:既然说是动态规划,那我们首先要考虑的就是怎么划分子问题,一般对于前面讲到的街道问题和数塔问题涉及走向的,考虑子问题时当然是想上一步是什么?但这个问题没有涉及走向,也没有所谓的上一步,该怎么办呢?既然是求公共子序列,也就有第一个序列的第i个字符和第二个序列的第j个字符相等的情况。
最长公共子序列问题LCS-Read

最长公共子序列问题LCS问题描述一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
确切地说,若给定序列X=<x1, x2,…, x m>,则另一序列Z=<z1, z2,…, z k>是X的子序列是指存在一个严格递增的下标序列<i1, i2,…, i k>,使得对于所有j=1,2,…,k有例如,序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2,3,5,7>。
给定两个序列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>是X和Y的一个公共子序列,序列<B, C, B, A>也是X和Y的一个公共子序列。
而且,后者是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。
最长公共子序列(LCS)问题:给定两个序列X=<x1, x2, …, x m>和Y=<y1, y2, … , y n>,要求找出X和Y的一个最长公共子序列。
参考解答动态规划算法可有效地解此问题。
下面我们按照动态规划算法设计的各个步骤来设计一个解此问题的有效算法。
1.最长公共子序列的结构解最长公共子序列问题时最容易想到的算法是穷举搜索法,即对X的每一个子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列,并且在检查过程中选出最长的公共子序列。
X的所有子序列都检查过后即可求出X和Y的最长公共子序列。
X 的一个子序列相应于下标序列{1, 2, …, m}的一个子序列,因此,X共有2m个不同子序列,从而穷举搜索法需要指数时间。
事实上,最长公共子序列问题也有最优子结构性质,因为我们有如下定理:定理: LCS的最优子结构性质设序列X=<x1, x2, …, x m>和Y=<y1, y2, …, y n>的一个最长公共子序列Z=<z1, z2, …,z k>,则:1.若x m=y n,则z k=x m=y n且Z k-1是X m-1和Y n-1的最长公共子序列;2.若x m≠y n且z k≠x m ,则Z是X m-1和Y的最长公共子序列;3.若x m≠y n且z k≠y n,则Z是X和Y n-1的最长公共子序列。
最长公共子序列问题

实验三最长公共子序列问题1. 实验环境本实验采用java 语言编写实现,环境:,编译器:eclipse2. 实验目的通过最长公共子序列问题,巩固并详细分析动态规划思想和解题步骤。
最长公共子序列的定义为:设有两个序列S i[1..m]和84仁n],需要寻找它们之间的一个最长公共子序列。
例如,假定有两个序列:81:I N T H E B E G I N N I N G82:A L L T H I N G 8 A R E L O 8 T则8i和S的一个最长公共子序列为THING又比如:81:A B C B D A B82:B D C A B A则它们的一个最长公共子序列为BCBA。
这里需要注意的是,一个子序列不一定必须是连续的,即中间可被其他字符分开,单它们的顺序必须是正确的。
另外,最长公共子序列不一定只有一个,而我们需要寻找的是其中一个。
当然,如果要求子序列里面的元素必须连成一片也是可以的。
实 际上,连成一片的版本比这里实现的更容易。
4.过程我们可以通过蛮力策略解决这个问题,步骤如下:1. 检查S1[1..m]里面每一个子序列。
2. 看看其是否也是S2[1..n]里的子序列。
3. 在每一步记录当前找到的子序列里面最长的子序列。
这种方法的效率十分低下。
因此本实验采用动态规划的方法实现 该算法。
利用动态规划寻找最长公共子序列步骤如下:1.寻找最长公共子序列的长度。
2.扩展寻找长度的算法来获取最长公共子序列。
策略:考虑序列S1和S2的前缀序列。
设 c[i ,j] = |LCS (S1[1..i],S2[1..j]),则有 c[m , n] = |LCS(S1S2)|所以有c[i ,j]=max{ c [ i - 1, j ], c[ i , j -1 ] },c[ i -1 , j -1 ] + 1,如要 S1[i] = S2[j]如果 S1[i]工 S2[j]然后回溯输出最长公共子序列过程:0 2 3 4 5 65.实现源代码p ackage Icsi mple; public classLCSImplem {断点调试及代码分析首先在main 方法里定义两个字符串,如: string strl = '*ABCBDAB*';String stu2 =CABA ";对这两个字符串,使它们的第一个字符为空,即初始化之后的c[][] 的第一行第一列,之所以要空出,是因为c[][]代表的是两个字符串数 组多少个,0的意思就是某个字符串的长度为 0。
数据结构与算法题解:最长公共子序列和最长公共子串

f [0][0] = 0, f [0][∗] = 0, f [∗][0] = 0,最后应该返回f [lenA][lenB]. 即 f 中索引与字符串串索引
ource, target)); }
}
二二、最⻓长公共子子串串
2.1 简单考虑
可以使用用两根指针索引分别指向两个字符串串的当前遍历位置,若遇到相等的字符时则同时向后移 动一一位。
public class Demo { public static int longestCommonSubstring(String A, String B) { if (A == null || A.length() == 0) return 0; if (B == null || B.length() == 0) return 0; int lenA = A.length(); int lenB = B.length(); int lcs = 0, lcs_temp = 0; for (int i = 0; i < lenA; ++i) { for (int j = 0; j < lenB; ++j) { lcs_temp = 0; while ((i + lcs_temp < lenA) && (j + lcs_temp < lenB) && (A.charAt(i + lcs_temp) == B.charAt(j + lcs_temp))) { ++lcs_temp; }
动态规划经典——最长公共子序列问题(LCS)和最长公共子串问题

动态规划经典——最长公共⼦序列问题(LCS)和最长公共⼦串问题⼀.最长公共⼦序列问题(LCS问题)给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共⼦序列,并返回其长度。
例如: A = "Hel lo W o rld" B = "loo p"则A与B的最长公共⼦序列为 "loo",返回的长度为3。
此处只给出动态规划的解法:定义⼦问题dp[i][j]为字符串A的第⼀个字符到第 i 个字符串和字符串B 的第⼀个字符到第 j 个字符的最长公共⼦序列,如A为“app”,B为“apple”,dp[2][3]表⽰ “ap” 和 “app” 的最长公共字串。
注意到代码中 dp 的⼤⼩为 (n + 1) x (m + 1) ,这多出来的⼀⾏和⼀列是第 0 ⾏和第 0 列,初始化为 0,表⽰空字符串和另⼀字符串的⼦串的最长公共⼦序列,例如dp[0][3]表⽰ "" 和“app” 的最长公共⼦串。
当我们要求dp[i][j],我们要先判断A的第i个元素B的第j个元素是否相同即判断A[i - 1]和 B[j -1]是否相同,如果相同它就是dp[i-1][j-1]+ 1,相当于在两个字符串都去掉⼀个字符时的最长公共⼦序列再加 1;否则最长公共⼦序列取dp[i][j - 1] 和dp[i - 1][j]中⼤者。
所以整个问题的初始状态为:dp[i][0]=0,dp[0][j]=0相应的状态转移⽅程为:dp[i][j]=max{dp[i−1][j],dp[i][j−1]},A[i−1]!=B[j−1] dp[i−1][j−1]+1,A[i−1]==B[j−1]代码的实现如下:class LCS{public:int findLCS(string A, int n, string B, int m){if(n == 0 || m == 0)//特殊输⼊return 0;int dp[n + 1][m + 1];//定义状态数组for(int i = 0 ; i <= n; i++)//初始状态dp[i][0] = 0;for(int i = 0; i <= m; i++)dp[0][i] = 0;for(int i = 1; i <= n; i++)for(int j = 1; j<= m; j++){if(A[i - 1] == B[j - 1])//判断A的第i个字符和B的第j个字符是否相同dp[i][j] = dp[i -1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j],dp[i][j - 1]);}return dp[n][m];//最终的返回结果就是dp[n][m]}};该算法的时间复杂度为O(n*m),空间复杂度为O(n*m)。
最长公共子序列问题

目录1 前言02 需求分析12.1 任务和要求12.2 运行环境12.3 开发工具13 分析和设计13.1 系统分析及设计思路13.2 主要数据结构及算法23.3 函数流程图24 具体代码实现35 课程设计总结135.1 程序运行结果或预期运行结果135.2 设计结论13参考文献14致谢141 前言若给定序列X={x1,x2,…,x m},则另一序列Z={z1,z2,…,z k},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。
例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定2个序列X和Y,当另一序列Z既是X的子序列又是Y 的子序列时,称Z是序列X和Y的公共子序列。
请使用C语言编程,设计一个有效的算法解决下述问题:给定2个序列X={x1,x2,…,x m}和Y={y1,y2,…,y n},找出X和Y 的最长公共子序列。
2 需求分析2.1任务和要求使用C语言编程,设计一个有效的算法解决下述问题:给定2个序列X={x1,x2,…,x m}和Y={y1,y2,…,y n},找出X和Y的最长公共子序列。
2.2运行环境(1)WINDOWS2000/XP系统(2)Visual C++ 6.0编译环境或TC编译环境2.3开发工具C语言3 分析和设计3.1 系统分析及设计思路设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则(1)若xm =yn,则zk=xm=yn,且zk-1是xm-1和yn-1的最长公共子序列。
(2)若xm ≠yn且zk≠xm,则Z是xm-1和Y的最长公共子序列。
(3)若xm ≠yn且zk≠yn,则Z是X和yn-1的最长公共子序列。
由此可见,2个序列的最长公共子序列包含了这2个序列的前缀的最长公共子序列。
动态规划解最长公共子序列问题

动态规划解最长公共子序列问题动态规划主要针对最优化问题,它的决策是全面考虑不同的情况分别进行决策,,最后通过多阶段决策逐步找出问题的最终解.当各个阶段采取决策后,会不断决策出新的数据,直到找到最优解.每次决策依赖于当前状态,又随机引起状态的转移.一个决策序列就是在变化的状态中产生出来的,故有”动态”的含义.所以,这种多阶段最优化决策解决问题的过程称为动态规划.一问题的描述与分析字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干字符(可能一个也不去掉)后形成的字符序列..令给定的字符序列X=”x0,x1,x2,…xm-1”,序列Y=”y0,y1,…yk-1”是X的子序列,存在X的一个严格递增下标序列i=i0,i1,i2,…ik-1,使得对所有的j=0,1,2,…k-1,有xi=yi。
例如X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。
给定两个序列A和B,称序列Z是A和B公共子序列,是指Z同是A和B的子序列。
求最长公共子序列。
若A的长度为m,B的长度为n,则A的子序列有2*m-1个,B的子序列有2*n-1个。
采用枚举法分别对A和B的所以子序列一一检查,最终求出最长公共子序列。
如此比较次数(2*2n)接近指数阶,当n较大时,算法太耗时,不可取。
所以要全面考虑不同的情况分别进行决策,,最后通过多阶段决策逐步找出问题的最终解.当各个阶段采取决策后,会不断决策出新的数据,直到找到最优解。
二、算法设计(或算法步骤)A=”a0,a1,a2,……am-1”,B=”b0,b1,b2,……bn-1”,且Z=”z0,z1,z2……zk-1”,为她们的最长公共子序列。
不难证明有一下结论:(1)如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,z2,……zk-2”是“a0,a1,a2,……am-2”和“b0,b1,b2,……bn-2”的一个最长公共子序列;(2)如果am-1!=bn-1,则若zk-1!=am-1,则“z0,z1,z2,……zk-1”是“a0,a1,a2,……am-2”和”b0,b1,b2,……bn-1”的一个最长公共子序列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法作业:LCS 问 题作业要求:设计一个算法求出两个序列的所有LCS ,分析最坏情况,用“会计方法”证明利用b[i][j]求出所有LCS 的算法在最坏情况下时间复杂度为)(mm n C O +1、 算法思路:根据最长公共子序列问题的性质,即经过分解后的子问题具有高度重复性,并且具有最优子结构性质,采用动态规划法求解问题。
设X={x 1, x 2, … , x n }, Y={y 1, y 2, … , y m }, 首先引入二维数组C[i][j]记录X i 和Y j 的LCS 的长度,定义C[i][j]如下:{j i jy i 且x ,i,j ]][j C[i jy i x j i j i C j i C j i C 00001110,]},1][[],][1[max{]][[===>+--≠>--=或,且为了构造出LCS ,还需要使用一个二维数组b[m][n],b[i][j]记录C[i][j]是通过哪个子问题的值求得的,以决定搜索的方向,欲求出所有的LCS ,定义数组b 如下: 设1-对角线方向;2-向上;3-向左;4-向上或向左 若X[i]=Y[j],b[i][j] = 1,若C[i-1][j]<i][j-1], 则b[i][j] = 2, 若C[i-1][j]>[i][j-1], 则b[i][j] = 3, 若C[i-1][j]=[i][j-1], 则b[i][j] = 4,根据以上辅助数组C 和b 的定义,算法首先需要求出这两个数组, C[m][n]中记录的最长公共子序列的长度,b 中记录了查找子序列元素的搜索方向。
利用C 和b 的信息,Find_All_LCS 可以采用回溯法求出所有的LCS 。
基本思路如下:使用一个辅助数组记录每次调用Find_All_LCS 得到的LCS 中的元素,每次递归调用一次Find_All_LCS ,进入一个新的执行层,首先要判断当前处理的两个子序列长度是否大于等于0 ,若不满足,则该层的递归结束,返回上一层;然后再判断当前得到的子序列是否等于数组C 中求出的最长公共子序列长度,若等于,则说明算法执行到此已经得到一个LCS ,按序输出;若不等于,此时根据数组b 中记录的搜索方向继续搜索,特别要说明的是,当b[i][j]=4时,即要向上或向左,需要对这两个方向分别调用Find_All_LCS ,保证沿着这两个方向上LCS 元素不被漏掉,都可以搜索到;若b[i][j]=1,即沿对角线方向搜索前进时,此时元素X[i]为LCS 中的元素,存放至辅助数组中去,同时将当前已经求得的LCS 长度增1,当递归调用Find_All_LCS 从b[i][j]=1处时,需要回溯一步,搜索其它路径上可能为LCS 中的元素。
当所有的可能路径都已经搜索完,算法结束。
对于某些情况会输出重复的LCS ,这是因为算法在沿不同路径搜索时可能会出现相同的LCS 序列。
2、 时间复杂度分析由上述对Find_All_LCS 算法的分析可知,求出所有的LCS 实际上是根据搜索的方向信息遍历所有的路径找出满足条件的元素集合。
因此,除求解辅助数组C 和b 所用的O(mn+m+n)的执行时间外,Find_All_LCS 的时间复杂度取决于所遍历路径数。
而路径数是由搜索方向决定的。
显然算法在最好的情况下,即m=n 并且b 中所有的值都指示沿着对角线方向搜索,时间复杂度为O(n). 相反,当X 和Y 序列不存在公共子序列时为算法的最坏情况,此时C 中所有值都等于0,数组b 中所有的值都指示要分别沿两个不同的方向(向左或向上)搜索,这种情况下每处理一次X[i],Y[j]时总是要沿两个方向分别调用Find_All_LCS ,遇到i=0或j=0时返回,直到搜索完所有的可能路径才结束,最坏情况下的搜索矩阵如下图所示:由此可知,要确定最坏情况的时间复杂度,就是要计算出从点),(n m 到i=0或j=0(除),(j i =(0,0)外)的所有路径。
求解转化为组合数学中的路径数问题。
建立一个直角坐标系如上图中所示,对于坐标系中的点可以沿向上或向左两个方向前进,设点),(n m S ,x 轴上的坐标点)0,(,...,0),...,0,2(),0,1(21m P )(i,P P P m i ,y 轴上的系列坐标点),0(,...,,0),...,2,0(),1,0(21n Q j)(Q Q Q n j ,其中m j n i ≤≤≤≤1,1.因为j i Q P 和是搜索路径的边界上的点,点1+i P 不能直接到达点i P ,点1+j Q 也不能直接到达j Q ,所以点),(n m S 到m i P P P P ,...,,...,,21和n j Q Q Q Q ,...,,...,,21的路径数等价于),(n m S 到点)1,('),...,1,('),...,1,2('),1,1('21m P i P P P m i 和点),1('),...,,1('),...,2,1('),1,1('21n Q j Q Q Q n j 的路径数,又因为点),(n m 到),(j i 路径数为i n j i n m C ---+,设总路径数为t ,则有∑∑=--+-=--+-+=mj jm j m n ni in in m C Ct 1111 根据组合数学的基本知识可得:()()m mn n m n n m n n m n m m n n m n n n m m n m m n m m n m n n m n mj jm jm n ni in in m C C C C C C C C C C C C C C C Ct ++-+--+--+--+---+--+---+--+=--+-=--+-===+=+=+++++++++=+=∑∑1111111011231201123121111...... [注]:参考卢开澄编著的《组合数学(第3版)》P34-P38最坏情况下算法搜索的所有路径为从S 到m i P P P P ,...,,...,,21和n j Q Q Q Q ,...,,...,,21的所有路径数mm n C +,因此算法在最坏情况下的时间复杂度为)(m m n C O +.3、 算法实现/*文件名:FindLongestCommonSequence.cpp 说明:求出两个序列中所有的最长公共子序列 日期:2005/10/12*/ #include <iostream> #include <string.h> #define MAXSIZE 100using namespace std;int C[MAXSIZE][MAXSIZE] ; //记录序列X和Y的LCS的长度int B[MAXSIZE][MAXSIZE] ;//记录二维数组C是通过哪一个子问题的值求得的,以决定搜索的方向:1-对角线方向;2-向上;3-向左;4-向上或向左char LCS[MAXSIZE];int len = 0;/*函数名:LCS_Len功能:自底向上进行递推计算C[i][j],并确定B中的搜索方向若i =0 或j =0 则C[i][j] = 0;若i,j > 0且x[i] = y[j] 则C[i][j] = C[i-1][j-1] + 1;若i,j > 0且x[i]!= y[j] 则C[i][j] = max{C[i-1][j],C[i][j-1])输入:两个序列X和Y输出:二维数组B和C*/void LCS_Len(char* X, char* Y){int m = strlen(X)-1;int n = strlen(Y)-1;for(int i = 0; i < m; i++ ) C[i][0] = 0;for(int j = 1; j < n; j++ ) C[0][j] = 0;for(i = 1;i <= m; i++ )for(j = 1; j <= n; j++ ){if( X[i] == Y[j] ){C[i][j] = C[i-1][j-1] + 1;B[i][j] = 1;}else if ( C[i-1][j] > C[i][j-1] ){C[i][j] = C[i-1][j];B[i][j] = 2;}else if ( C[i-1][j] < C[i][j-1] ){C[i][j] = C[i][j-1];B[i][j] = 3;}else /*C[i-1][j] == C[i][j-1]*/{C[i][j] = C[i-1][j];B[i][j] = 4;}}}函数名:Fine_All_LCS功能:回溯法递归输出所有的LCS参数说明:Direction : 记录搜索方向的二维数组,1-对角线方向;2-向上;3-向左;4-向上或向左X : 一个序列i,j : 待搜索的下标,初始值为两个序列的长度len: 记录当前LCS的长度lcslen: LCS的长度LCS:记录当前得到的LCS字符*/void Find_All_LCS(int Direction[MAXSIZE][MAXSIZE], char* X, int i, int j, int curlen, int lcslen) {if(i>=0 && j>=0){if(len == lcslen)//如果当前lcs的长度等于已知的LCS的长度则输出子序列{for( int k = len - 1 ; k >= 0 ; k-- )cout << LCS[k];cout << "\n";}else{if(Direction[i][j] == 1){LCS[curlen] = X[i];len++; //子序列长度加1Find_All_LCS(Direction, X, i-1, j-1, curlen + 1, lcslen);//沿对角线方向搜索len--; //回溯}else if(Direction[i][j] == 2){Find_All_LCS(Direction, X, i-1, j, curlen, lcslen);}else if(Direction[i][j] == 3){Find_All_LCS(Direction, X, i, j-1, curlen, lcslen);}else //递归调用Find_All_LCS分别沿两个不同的方向搜索{Find_All_LCS(Direction, X, i, j-1, curlen, lcslen);Find_All_LCS(Direction, X, i-1, j, curlen, lcslen);}}}int main(){char *x, *y;x = " ABCBDAB";//0单元未用,下标从1开始y = " BDCABA";int m = (int)strlen(x)-1;int n = (int)strlen(y)-1;int lcslen;cout << "x =" << x << endl;cout << "y =" << y << endl;cout << "The longest common sequence as following:" << endl;LCS_Len(x, y);lcslen = C[m][n];Find_All_LCS(B, x, m, n, 0, lcslen);cout << "OK!";return 0;}4、运行效果运行效果演示:。