动态规划解最长公共子序列问题
动态规划法求解最长公共子序列(含Java代码)

公共子序列问题徐康123183一.算法设计假设有两个序列X和Y,假设X和Y分别有m和n个元素,则建立一个二维数组C[(m+1)*(n+1)],记录X i与Y j的LCS的长度。
将C[i,j]分为三种情况:若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]}。
再使用一个m*n的二维数组b,b[i,j]记录C[i,j]的来向:若X[i]=Y[j],则B[i,j]中记入“↖”,记此时b[i,j] = 1;若X[i] Y[j]且C[i-1,j] > C[i,j-1],则b[i,j]中记入“↑”,记此时B[i,j] = 2;若X[i] Y[j]且C[i-1,j] < C[i,j-1],则b[i,j]中记入“←”,记此时B[i,j] = 3;若X[i]Y[j]且C[i-1,j] = C[i,j-1],则b[i,j]中记入“↑”或“←”,记此时B[i,j] = 4;得到了两个数组C[]和B[],设计递归输出LCS(X,Y)的算法:LCS_Output(Direction[][], X[], i, j, len,LCS[]){If i=0 or j=0 将LCS[]保存至集合LCS_SET中then return;If b[i,j]=1 then /*X[i]=Y[j]*/{LCS_Output(b,X,i-1,j-1);将X[i]保存至LCS[len-i];}else if b[i,j]=2 then /*X[i]Y[j]且C[i-1,j]>C[i,j-1]*/LCS_Output(b,X,i-1,j)else if b[i,j]=3 then /*X[i]Y[j]且C[i-1,j]<C[i,j-1]*/ LCS_Output(b,X,i,j-1)else if b[i,j]=4 then /*X[i]Y[j]且C[i-1,j]=C[i,j-1]*/LCS_Output(b,X,i-1,j)LCS_Output(b,X,i,j-1)}二.算法时间复杂度分析由上述对算法的分析得知,求辅助数组C 和B 所消耗的时间复杂度为O (mn ),而查找所有的公共子序列的时间复杂度取决于所遍历的路径,而路径是由算法递归的方向决定的。
求解两个序列的最长公共子序列的递推次序

最长公共子序列(Longest Common Subsequence, LCS)是指在两个序列中找到的最长公共非连续子序列。
求解两个序列的最长公共子序列的递推次序是一道经典的动态规划问题,本文将针对这一主题展开详细的描述和分析。
一、问题描述给定两个序列X={x1, x2, ..., xm}和Y={y1, y2, ..., yn},要求找出它们的最长公共子序列。
对于序列X={A, B, C, B, D, A, B}和Y={B, D, C, A, B, A},它们的最长公共子序列是{B, C, A, B},长度为4。
二、递推关系在动态规划的思想下,我们可以通过构造一个二维数组来解决这个问题。
假设L[i][j]表示序列X的前i个元素和序列Y的前j个元素的最长公共子序列的长度,那么L[i][j]的递推关系可以表示为:1. 当i=0或j=0时,L[i][j]=0;2. 当xi=yj时,L[i][j]=L[i-1][j-1]+1;3. 当xi≠yj时,L[i][j]=max{L[i-1][j], L[i][j-1]}。
三、动态规划的实现在实际编程中,我们可以使用一个二维数组来存储L[i][j]的值。
我们需要初始化L[0][j]和L[i][0]为0;根据上述递推关系,使用一个双重循环来填充数组L,最终得到L[m][n]的值,即序列X和Y的最长公共子序列的长度。
四、回溯求解最长公共子序列在获得了二维数组L之后,我们可以通过回溯的方法来求解最长公共子序列的具体内容。
从L[m][n]开始,我们可以根据递推关系,逆向推导出最长公共子序列的元素,直到回溯到L[0][0]为止。
这样就可以得到最长公共子序列的具体内容。
五、优化在实际应用中,为了提高动态规划的效率,可以对上述算法进行优化。
例如使用滚动数组来降低空间复杂度,或者采用其他策略来减少不必要的计算。
六、总结本文针对求解两个序列的最长公共子序列的递推次序进行了详细的分析和描述。
利用递归求最长公共子序列问题

利用递归求最长公共子序列问题1.引言最长公共子序列(Longest Common Subsequence,简称LCS)是一个经典的动态规划问题,其可以描述为:给定两个序列X和Y,求出它们的最长公共子序列的长度。
在计算机科学领域,LCS问题广泛应用于字符串比较、文本相似度计算、基因序列比对等领域,因此对于LCS问题的求解具有重要的意义。
2.问题描述对于序列X和Y,它们的最长公共子序列可以定义为:如果一个序列Z既是X的子序列又是Y的子序列,且Z的长度最大,那么Z称为X和Y的最长公共子序列。
3.递归解法我们可以使用递归的方式来解决LCS问题。
递归的思想是将原问题划分为更小的子问题求解,然后将子问题的解合并起来得到原问题的解。
对于LCS问题,我们可以将其划分为更小的子问题求解。
假设X和Y的长度分别为m和n,我们可以考虑X中的第m个元素和Y中的第n 个元素是否相等,从而将原问题划分为以下三种情况:a) 如果X[m]等于Y[n],那么X和Y的最长公共子序列就是X[1..m-1]和Y[1..n-1]的最长公共子序列再加上X[m]。
b) 如果X[m]不等于Y[n],那么X和Y的最长公共子序列就是X[1..m-1]和Y[1..n]的最长公共子序列,或者是X[1..m]和Y[1..n-1]的最长公共子序列,取两者的最大值。
c) 如果X或Y的长度为0,那么它们的最长公共子序列的长度为0。
4.递归求解步骤基于上述的划分情况,我们可以得到递归求解LCS问题的步骤如下:a) 如果X和Y的最后一个元素相等,那么LCS(X, Y, m, n) = 1 + LCS(X, Y, m-1, n-1);b) 如果X和Y的最后一个元素不相等,那么LCS(X, Y, m, n) = max(LCS(X, Y, m-1, n), LCS(X, Y, m, n-1));c) 如果m等于0或n等于0,那么LCS(X, Y, m, n) = 0。
0011算法笔记——【动态规划】最长公共子序列问题(LCS)

问题描述:一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
确切地说,若给定序列X= { x1, x2,…, x m},则另一序列Z= {z1, z2,…, z k}是X的子序列是指存在一个严格递增的下标序列{i1, i2,…, i k},使得对于所有j=1,2,…,k有X ij=Z j。
例如,序列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的公共子序列。
给定两个序列X= {x1, x2, …, x m}和Y= {y1, y2, … , y n},要求找出X和Y的一个最长公共子序列。
问题解析:设X= { A, B, C, B, D, A, B},Y= {B, D, C, A, B, A}。
求X,Y的最长公共子序列最容易想到的方法是穷举法。
对X的多有子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列。
由集合的性质知,元素为m的集合共有2^m个不同子序列,因此,穷举法需要指数级别的运算时间。
进一步分解问题特性,最长公共子序列问题实际上具有最优子结构性质。
设序列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的最长公共子序列。
用动态规划法解决最长公共子序列问题

用动态规划法解决最长公共子序列问题动态规划解最长子序列一、课程设计目的掌握动态规划法的原理,并能够按其原理编程实现求两个序列数据的最长公共子系列,以加深对其的理解。
二、课程设计内容1、用动态规划法解决最长子序列问题2、交互输入两个序列数据3、输出两个序列的最长公共子序列三、概要设计四、详细设计与实现#include "iostream.h"#include "iomanip.h"#define max 100void LCSLength(int m,int n,char *x,char *y,char *b){int i,j,k;int c[max][max];for(i=1;i<=m;i++){c[i][0]=0;}for(i=1;i<=n;i++){c[0][i]=0;}for(i=1;i<=m;i++){for(j=1;j<=n;j++){if(x[i-1]==y[j-1]){c[i][j]=c[i-1][j-1]+1;k=i*(n+1)+j;b[k]='\\';}else if(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];k=i*(n+1)+j;b[k]='|';}else{c[i][j]=c[i][j-1];k=i*(n+1)+j;b[k]='-';}}}}void LCS(int i,int j,char *x,char *b,int width) {if(i==0 || j==0)return;int k=i*(width+1)+j;if(b[k]=='\\'){LCS(i-1,j-1,x,b,width);cout<<x[i]<<endl;}else if(b[k]=='|'){LCS(i-1,j,x,b,width);}else{LCS(i,j-1,x,b,width);}}void main(){char x[max]={'a','b','c','b','d','a','b'};char y[max]={'b','d','c','a','b','a'};int m=7;int n=6;char b[max]={0};LCSLength(m,n,x,y,b);LCS(m,n,x,b,n);cout<<endl<<endl;}最长公共子序列问题具有最优子结构性质设X = { x1 , ... , xm }Y = { y1 , ... , yn }及它们的最长子序列Z = { z1 , ... , zk }则1、若 xm = yn ,则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列2、若 xm != yn ,且 zk != xm , 则 Z 是 X[m-1] 和 Y 的最长公共子序列3、若 xm != yn , 且 zk != yn , 则 Z 是 Y[n-1] 和 X 的最长公共子序列由性质导出子问题的递归结构当 i = 0 , j = 0 时 , c[i][j] = 0当 i , j > 0 ; xi = yi 时 , c[i][j] = c[i-1][j-1] + 1当 i , j > 0 ; xi != yi 时 , c[i][j] = max { c[i][j-1] , c [i-1][j] }#include<iostream.h>#define max(a,b) a>b?a:b#define M 100void display(int &n,int &C,int w[M],int v[M]) {int i;cout<<"请输入物品种数n:";cin>>n;cout<<endl;cout<<"请输入背包总容量C:";cin>>C;cout<<endl;cout<<"请输入各物品的大小或重量w:"<<endl;w[0]=0;for(i=1;i<=n;i++)cin>>w[i];cout<<"请输入各物品其价值v:"<<endl;v[0]=0;for(i=1;i<=n;i++)cin>>v[i];};int knapsack(int &n,int &C,int w[M],int v[M],int V[M][M]){int i,j;for (i=0;i<=n;i++)for(j=0;j<=C;j++){if(i==0||j==0)V[i][j]=0;else if(w[i]>j)V[i][j]=V[i-1][j];else if(w[i]<=j)V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);}return V[n][C];};void traceback(int n,int C,int w[M],int x[M],int V[M][M]){for(int i=1;i<=n;i++){if(V[i][C]==V[i-1][C])x[i]=0;else{x[i]=1;C=C-w[i];}}//x[n]=(V[n][C]>0)?1:0;};void main(){int i,j,n,C;char ch;int w[M],v[M],x[M];int V[M][M];while(1){display(n,C,w,v);cout<<"运算结果如下:"<<endl;for(i=1;i<=n;i++)x[i]=0;knapsack(n,C,w,v,V);cout<<" ";for(j=0;j<=C;j++)cout<<j<<" ";cout<<endl;for(i=0;i<=n;i++){cout<<i<<" ";for(j=0;j<=C;j++){cout<<V[i][j]<<" ";}cout<<endl;cout<<endl;}cout<<"选择的物向量表示为:";cout<<" ( ";traceback(n,C,w,x,V);for(i=1;i<=n;i++)cout<<x[i]<<" ";cout<<")"<<endl;cout<<"背包最大价值为:"<<V[n][C]<<endl;cout<<endl;cout<<"按Y或y继续操作,否则按任意键"<<endl;cin>>ch;if(ch=='Y'||ch=='y')continue;elsebreak;} }。
最长公共子序列问题;

最长公共子序列问题;最长公共子序列(Longest Common Subsequence, LCS)问题是指找到多个字符串中最长的公共子序列。
公共子序列是指这些字符串在所有字符串中都以相同的顺序出现,但不要求连续。
例如,对于字符串"ABCD"和"ACDF",其最长公共子序列为"ACD"。
最长公共子序列问题可以通过动态规划来解决。
基本思路是使用一个二维数组dp,其中dp[i][j]表示字符串A的前i个字符和字符串B的前j个字符的最长公共子序列的长度。
首先,初始化dp[0][j]和dp[i][0]为0,表示空字符串与任何字符串的最长公共子序列长度为0。
然后,对于每个字符A[i]和B[j],如果A[i]等于B[j],则dp[i][j] = dp[i-1][j-1] + 1,表示在之前的最长公共子序列长度的基础上加1。
否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1]),表示要么在字符串A的前i-1个字符和字符串B的前j个字符的最长公共子序列的基础上取得,要么在字符串A的前i个字符和字符串B的前j-1个字符的最长公共子序列的基础上取得。
最终,dp[m][n]即为所求,其中m和n分别为字符串A和字符串B的长度。
可以通过追踪dp数组来还原出最长公共子序列,具体方法是从dp[m][n]开始,如果A[i]等于B[j],则该字符是公共字符,将其加入结果序列,然后向左上方移动,即dp[i-1][j-1]。
如果dp[i][j]等于dp[i-1][j],则说明最长公共子序列在A中取得,向上移动,即dp[i-1][j];如果dp[i][j]等于dp[i][j-1],则说明最长公共子序列在B中取得,向左移动,即dp[i][j-1]。
重复上述过程,直到dp[i][j]为0。
公共解的三种解法

公共解的三种解法
#### 1. 动态规划
使用动态规划的方法,可以把求解最大公共子序列问题转换为求解最长公共子序列问题。
动态规划的思路是:令dp[i][j]表示字符串A[0..i]和字符串B[0..j]的最长公共子序列的长度,则有状态转移方程:
```
dp[i][j] =
0 (i == 0 || j == 0)
dp[i-1][j-1] + 1 (A[i] == B[j])
max(dp[i-1][j], dp[i][j-1]) (A[i] != B[j])
```
最终结果为dp[n][m],其中n为字符串A的长度,m为字符串B的长度。
#### 2. 递归
递归的思路是:令lcs(i, j)表示字符串A[0..i]和字符串B[0..j]的最长公共子序列的长度,则
有状态转移方程:
```
lcs(i, j) =
0 (i == 0 || j == 0)
lcs(i-1, j-1) + 1 (A[i] == B[j])
max(lcs(i-1, j), lcs(i, j-1)) (A[i] != B[j])
```
最终结果为lcs(n, m),其中n为字符串A的长度,m为字符串B的长度。
#### 3. 滑动窗口
滑动窗口的思路是:定义两个指针i和j,分别指向字符串A和字符串B的开头,比较A[i]
和B[j]的值,如果相等,则将i和j同时向后移动,否则只有一个指针向后移动,直到两个
指针都到达字符串末尾。
最终结果为i和j指针移动的次数,即为最长公共子序列的长度。
算法设计最长公共子序列

算法设计最长公共子序列动态规划是一种将大问题分解为多个相互重叠的子问题的方法。
在LCS算法中,我们将两个字符串的比较拆分为子问题,然后通过子问题的解决来解决整个问题。
算法步骤如下:1. 初始化一个二维数组dp[m+1][n+1],其中m和n分别是两个字符串的长度,dp[i][j]表示字符串1的前i个字符和字符串2的前j个字符之间的LCS的长度。
2. 将dp的第一行和第一列初始化为0,表示空字符串和任何其他字符串之间的LCS的长度都为0。
3.使用两个循环迭代字符串1和字符串2的每个字符。
从1开始,递增地遍历每个字符的位置。
4. 比较当前字符是否相等。
如果相等,则将dp[i][j]设置为dp[i-1][j-1]+1,表示LCS的长度增加15. 如果当前字符不相等,则将dp[i][j]设为dp[i-1][j]和dp[i][j-1]中的最大值,表示LCS的长度不变。
6.继续向前迭代不同字符的位置,直到处理完所有字符。
7. 当迭代完成后,dp[m][n]的值即为字符串1和字符串2的最长公共子序列的长度。
8. 可以使用回溯法来找到LCS本身。
从dp[m][n]位置开始,根据dp[i][j]的值,在字符串1和字符串2中向左上方移动,直到dp[i][j]等于0。
这样就找到了最长公共子序列。
该算法的时间复杂度为O(m*n),其中m和n分别是两个字符串的长度。
这是因为遍历了两个字符串的所有字符,并在每个字符位置上进行了常量时间的比较和更新。
LCS算法可以应用于多个领域,包括字符串处理、DNA序列分析、版本控制系统等。
通过找到最长公共子序列,可以找到相似的字符或序列,并从中提取有用的信息。
例如,对于字符串1:"ABCBDAB"和字符串2:"BDCAB",可以使用LCS算法找到它们的最长公共子序列为:"BCAB",其长度为4。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态规划解最长公共子序列问题动态规划主要针对最优化问题,它的决策是全面考虑不同的情况分别进行决策,,最后通过多阶段决策逐步找出问题的最终解.当各个阶段采取决策后,会不断决策出新的数据,直到找到最优解.每次决策依赖于当前状态,又随机引起状态的转移.一个决策序列就是在变化的状态中产生出来的,故有”动态”的含义.所以,这种多阶段最优化决策解决问题的过程称为动态规划.一问题的描述与分析字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干字符(可能一个也不去掉)后形成的字符序列..令给定的字符序列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”的一个最长公共子序列。
(3)如果am-1!=bn-1,则若zk-1!=bn-1,则“z0,z1,z2,……zk-1”是“a0,a1,a2,……am-1”和“b0,b1,b2,……bn-2”的一个最长公共子序列。
如此找到了原问题与其子问题的递归关系。
基本存储结构是存储两个字符串及其最长公共子序列的3个一位数组。
当然要找出最长公共子序列,要存储当前最长公共子序列的长度和当前公共子序列的长度,而若只存储当前信息,最后只能求解最长公共子序列的长度,却不能找到最长公共子序列本身。
因此需建立一个(n+1)*(m+1)的二维数组c,c[i][j]存储序列“a0,a1,a2……ai-2”和“b0,b1,……bj-1”的最长公共子序列长度,由上递推关系分析,计算c[i][j]可递归的表述如下:(1)c[i][j]=0 如果i=0或j=0;(2)c[i][j]=c[i-1][j-1]+1 如果i,j>0,且a[i-1]=b[j-1](3)c[i][j]=max(c[i][j-1],c[i-1][j]) 如果i,j>0,且a[i-1]!=b[j-1]以此可写出计算两个序列的最长公共子序列的长度函数,最终求解出c[m][n].三、算法实现由二维数组c的递归定义,c[i][j]的结果仅依赖于c[i-1][j-1],c[i-1][j]和c[i][j-1].可以从c[m][n]开始,跟踪c[i][j]结果的产生过程,从而逆向构造最长公共子序列。
# include <stdio.h># include <string.h>#define N 100/*字符串的最大长度限制*/char a[ N ],/*第一个字符串*/b[ N ],/*第二个字符串*/str[ N ];/*用于存放a 与b的公共子序列*//*计算两个序列的最长公共子序列的长度*/int lcs_len( char *a, char *b, int c[][ N ] ){int m = strlen( a ),/*计算两个序列的长度*/n = strlen( b ),i,/*行指针*/j;/*列指针*/for( i = 0; i <= m; i++ ) c[ i ][ 0 ] = 0;/*j==0表示b串长度为0,无论a串多长,两者的公共子序列长度为0*/for( j = 1; j <= n; j++ ) c[ 0 ][ j ] = 0;/*根据上一个类推*/for( i = 1; i <= m; i++ )/*开始递推*/for( j = 1; j <= n; j++ )/*若两序列的最后一个字符相同,那么公共子序列长度为去掉这最后一个字符后新生成的两个串的公共子序列长度+1*/if( a[ i - 1 ] == b[ j - 1 ]){ c[ i ][ j ] = c[ i - 1 ][ j - 1 ] + 1;printf("\nc[ %d ][ %d ] = c[ %d - 1 ][ %d - 1 ] + 1\n", i, j, i, j );}/**/else if( c[ i - 1 ][ j ] >= c[ i ][ j -1 ] ){ c[ i ][ j ] = c[ i - 1 ][ j ];printf("\nc[ %d ][ %d ] = c[ %d - 1 ][ %d ]\n", i, j, i, j );}/*若两序列最后一个字符不同,那么他们最大子序列的长度为c[ i - 1][j]和c[i][j-1]中较大的一个*/else{c[ i ][ j ] = c[ i ][ j -1 ];printf("\nc[ %d ][ %d ] = c[ %d ][ %d - 1]\n", i, j, i, j);}/*调试:将生成的数组方阵显示出来,m行,n列*/printf("\n");printf(" ");for( j = 0; j <= n; j++ )printf("%d, ", j );/*显示列标号*/printf("\n");for( i = 0; i <= m; i++ ){printf("%d: ", i );/*显示行标号*/for( j = 0; j <= n; j++ )printf("%d, ", c[ i ][ j ] );printf("\n");/*一行显示完,换下一行*/}return c[ m ][ n ];/*结果:a与b的最大子序列长度存在c[m][n]中*/}/*构造最长子序列函数*/char *build_lcs( char s[], char *a, char *b ){/*根据lcs_len()函数计算的结果,倒推出最长子序列,结果放在s[]中*/int k,/*a与b最长子序列的长度*/i = strlen( a ),/*a串长度*/j = strlen( b ),/*b*/c[ N ][ N ];/*存放全部的计算过程,动态规划,体现在这个地方,中间计算结果都在这里*/k = lcs_len( a, b, c );/*将c[][]传给lcs_len()计算并求出长度,将中间结果放在c[][]中*/s[ k ] = '\0';/*s串的结束标记*/while( k > 0 )/*开始倒推*/if( c[ i ][ j ] == c[ i - 1 ][ j ] ) i --;else if( c[ i ][ j ] == c[ i ][ j -1 ]) j--;else{ s[ --k ] = a[ i - 1 ];/*将一个公共字符存入s中*/i--;j--;}return s;}/*测试程序*/void main(){printf("Enter two string(<%d)!\n", N );scanf( "%s%s", a,b );printf("LCS = %s\n", build_lcs( str, a, b ));}以X=”ABCBDAB”与Y=”BDCABA”为例,两字符串算法实现求解最长公共子序列的长度和最长公共子序列的求解过程。
Enter two string(<100)!a,b,ca,b,c,dc[ 1 ][ 1 ] = c[ 1 - 1 ][ 1 - 1 ] + 1c[ 1 ][ 2 ] = c[ 1 ][ 2 - 1]c[ 1 ][ 3 ] = c[ 1 ][ 3 - 1]c[ 1 ][ 4 ] = c[ 1 ][ 4 - 1]c[ 1 ][ 5 ] = c[ 1 ][ 5 - 1]c[ 1 ][ 6 ] = c[ 1 ][ 6 - 1]c[ 1 ][ 7 ] = c[ 1 ][ 7 - 1]c[ 2 ][ 2 ] = c[ 2 - 1 ][ 2 - 1 ] + 1 c[ 2 ][ 3 ] = c[ 2 ][ 3 - 1]c[ 2 ][ 4 ] = c[ 2 - 1 ][ 4 - 1 ] + 1 c[ 2 ][ 5 ] = c[ 2 ][ 5 - 1]c[ 2 ][ 6 ] = c[ 2 - 1 ][ 6 - 1 ] + 1 c[ 2 ][ 7 ] = c[ 2 ][ 7 - 1]c[ 3 ][ 1 ] = c[ 3 - 1 ][ 1 ]c[ 3 ][ 2 ] = c[ 3 - 1 ][ 2 ]c[ 3 ][ 3 ] = c[ 3 - 1 ][ 3 - 1 ] + 1 c[ 3 ][ 4 ] = c[ 3 ][ 4 - 1]c[ 3 ][ 5 ] = c[ 3 ][ 5 - 1]c[ 3 ][ 6 ] = c[ 3 ][ 6 - 1]c[ 3 ][ 7 ] = c[ 3 ][ 7 - 1]c[ 4 ][ 1 ] = c[ 4 - 1 ][ 1 ]c[ 4 ][ 2 ] = c[ 4 - 1 ][ 2 - 1 ] + 1 c[ 4 ][ 3 ] = c[ 4 - 1 ][ 3 ]c[ 4 ][ 4 ] = c[ 4 - 1 ][ 4 - 1 ] + 1 c[ 4 ][ 5 ] = c[ 4 ][ 5 - 1]c[ 4 ][ 6 ] = c[ 4 - 1 ][ 6 - 1 ] + 1 c[ 4 ][ 7 ] = c[ 4 ][ 7 - 1]c[ 5 ][ 1 ] = c[ 5 - 1 ][ 1 ]c[ 5 ][ 3 ] = c[ 5 - 1 ][ 3 ]c[ 5 ][ 4 ] = c[ 5 - 1 ][ 4 ]c[ 5 ][ 5 ] = c[ 5 - 1 ][ 5 - 1 ] + 1 c[ 5 ][ 6 ] = c[ 5 ][ 6 - 1]c[ 5 ][ 7 ] = c[ 5 ][ 7 - 1]0, 1, 2, 3, 4, 5, 6, 7,0: 0, 0, 0, 0, 0, 0, 0, 0,1: 0, 1, 1, 1, 1, 1, 1, 1,2: 0, 1, 2, 2, 2, 2, 2, 2,3: 0, 1, 2, 3, 3, 3, 3, 3,4: 0, 1, 2, 3, 4, 4, 4, 4,5: 0, 1, 2, 3, 4, 5, 5, 5,LCS = a,b,cPress any key to continue Enter two string(<100)!w,e,r,t,yw,r,t,ec[ 1 ][ 1 ] = c[ 1 - 1 ][ 1 - 1 ] + 1 c[ 1 ][ 2 ] = c[ 1 ][ 2 - 1]c[ 1 ][ 3 ] = c[ 1 ][ 3 - 1]c[ 1 ][ 4 ] = c[ 1 ][ 4 - 1]c[ 1 ][ 5 ] = c[ 1 ][ 5 - 1]c[ 1 ][ 6 ] = c[ 1 ][ 6 - 1]c[ 1 ][ 7 ] = c[ 1 ][ 7 - 1]c[ 2 ][ 1 ] = c[ 2 - 1 ][ 1 ]c[ 2 ][ 2 ] = c[ 2 - 1 ][ 2 - 1 ] + 1 c[ 2 ][ 3 ] = c[ 2 ][ 3 - 1]c[ 2 ][ 4 ] = c[ 2 - 1 ][ 4 - 1 ] + 1 c[ 2 ][ 5 ] = c[ 2 ][ 5 - 1]c[ 2 ][ 6 ] = c[ 2 - 1 ][ 6 - 1 ] + 1 c[ 2 ][ 7 ] = c[ 2 ][ 7 - 1]c[ 3 ][ 1 ] = c[ 3 - 1 ][ 1 ]c[ 3 ][ 2 ] = c[ 3 - 1 ][ 2 ]c[ 3 ][ 3 ] = c[ 3 - 1 ][ 3 ]c[ 3 ][ 4 ] = c[ 3 - 1 ][ 4 ]c[ 3 ][ 5 ] = c[ 3 - 1 ][ 5 ]c[ 3 ][ 6 ] = c[ 3 - 1 ][ 6 ]c[ 3 ][ 7 ] = c[ 3 - 1 ][ 7 - 1 ] + 1 c[ 4 ][ 1 ] = c[ 4 - 1 ][ 1 ]c[ 4 ][ 2 ] = c[ 4 - 1 ][ 2 - 1 ] + 1 c[ 4 ][ 3 ] = c[ 4 - 1 ][ 3 ]c[ 4 ][ 4 ] = c[ 4 - 1 ][ 4 - 1 ] + 1 c[ 4 ][ 5 ] = c[ 4 ][ 5 - 1]c[ 4 ][ 6 ] = c[ 4 - 1 ][ 6 - 1 ] + 1 c[ 4 ][ 7 ] = c[ 4 - 1 ][ 7 ]c[ 5 ][ 1 ] = c[ 5 - 1 ][ 1 ]c[ 5 ][ 2 ] = c[ 5 - 1 ][ 2 ]c[ 5 ][ 3 ] = c[ 5 - 1 ][ 3 - 1 ] + 1 c[ 5 ][ 4 ] = c[ 5 - 1 ][ 4 ]c[ 5 ][ 5 ] = c[ 5 - 1 ][ 5 ]c[ 5 ][ 6 ] = c[ 5 - 1 ][ 6 ]c[ 5 ][ 7 ] = c[ 5 - 1 ][ 7 ]c[ 6 ][ 1 ] = c[ 6 - 1 ][ 1 ]c[ 6 ][ 2 ] = c[ 6 - 1 ][ 2 - 1 ] + 1 c[ 6 ][ 3 ] = c[ 6 - 1 ][ 3 ]c[ 6 ][ 4 ] = c[ 6 - 1 ][ 4 - 1 ] + 1 c[ 6 ][ 5 ] = c[ 6 ][ 5 - 1]c[ 6 ][ 6 ] = c[ 6 - 1 ][ 6 - 1 ] + 1 c[ 6 ][ 7 ] = c[ 6 ][ 7 - 1]c[ 7 ][ 1 ] = c[ 7 - 1 ][ 1 ]c[ 7 ][ 2 ] = c[ 7 - 1 ][ 2 ]c[ 7 ][ 3 ] = c[ 7 - 1 ][ 3 ]c[ 7 ][ 4 ] = c[ 7 - 1 ][ 4 ]c[ 7 ][ 5 ] = c[ 7 - 1 ][ 5 - 1 ] + 1 c[ 7 ][ 6 ] = c[ 7 ][ 6 - 1]c[ 7 ][ 7 ] = c[ 7 ][ 7 - 1]c[ 8 ][ 1 ] = c[ 8 - 1 ][ 1 ]c[ 8 ][ 2 ] = c[ 8 - 1 ][ 2 - 1 ] + 1 c[ 8 ][ 3 ] = c[ 8 - 1 ][ 3 ]c[ 8 ][ 4 ] = c[ 8 - 1 ][ 4 - 1 ] + 1 c[ 8 ][ 5 ] = c[ 8 - 1 ][ 5 ]c[ 8 ][ 6 ] = c[ 8 - 1 ][ 6 - 1 ] + 1 c[ 8 ][ 7 ] = c[ 8 ][ 7 - 1]c[ 9 ][ 1 ] = c[ 9 - 1 ][ 1 ]c[ 9 ][ 2 ] = c[ 9 - 1 ][ 2 ]c[ 9 ][ 3 ] = c[ 9 - 1 ][ 3 ]c[ 9 ][ 4 ] = c[ 9 - 1 ][ 4 ]c[ 9 ][ 5 ] = c[ 9 - 1 ][ 5 ]c[ 9 ][ 6 ] = c[ 9 - 1 ][ 6 ]c[ 9 ][ 7 ] = c[ 9 - 1 ][ 7 ]0, 1, 2, 3, 4, 5, 6, 7,0: 0, 0, 0, 0, 0, 0, 0, 0,1: 0, 1, 1, 1, 1, 1, 1, 1,2: 0, 1, 2, 2, 2, 2, 2, 2,3: 0, 1, 2, 2, 2, 2, 2, 3,4: 0, 1, 2, 2, 3, 3, 3, 3,5: 0, 1, 2, 3, 3, 3, 3, 3,6: 0, 1, 2, 3, 4, 4, 4, 4,7: 0, 1, 2, 3, 4, 5, 5, 5,8: 0, 1, 2, 3, 4, 5, 6, 6,9: 0, 1, 2, 3, 4, 5, 6, 6,LCS = w,r,t,Press any key to continue。