最长公共子序列计算及打印

题目描述:从a,b俩数组中找出共有的最长子序列,如a={1,2,3,5,6,4,8},b={1,1,2,5,5,3,5,7,6,},其最长公共子序列为{1,2,3,5,6}.

解决方法:动态规划,寻找子问题,可以发现,当前的最长子序列一定等于上一次的加一,否则,就等于上一次的。

即:c[i][j]=0;               当i==0或j==0时

c[i][j]=c[i-1][j-1]+1.   当a[i]=b[j]时

c[i][j]=c[i-1][j].       当c[i-1][j]>c[i][j-1]时

c[i][j]=c[i][j-1].       当c[i][j-1]>c[i][j-1]时

i和j分别表示数组a中前i个和数组b中前j个的最长公共子序列.

代码如下:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 using namespace std;
 5 int longque(int m,int n,int *a,int *b,int **c,int **flag)
 6 {
 7     for(int i=0;i<=n;i++)      //初始化0行0列
 8         c[i][0]=0;
 9     for(int i=0;i<=m;i++)
10         c[0][i]=0;
11
12         int max1=0;
13     for(int i=1;i<=n;i++)
14     {
15         for(int j=1;j<=m;j++)
16         {
17             if(a[i]==b[j])         //相等时+1,标标记为1
18                {
19                   c[i][j]=c[i-1][j-1]+1;flag[i][j]=1;
20                }
21             else if(c[i-1][j]>c[i][j-1]){        //不相等时,取大的并标记
22                 c[i][j]=c[i-1][j];  flag[i][j]=2;
23             }else{
24                 c[i][j]=c[i][j-1]; flag[i][j]=3;
25             }
26             max1=max(max1,c[i][j]);
27         }
28
29     }
30
31      return max1;
32 }
33 void LCS(int i,int j,int **flag,int *a)
34 {
35     if(i==0||j==0)return;
36     if(flag[i][j]==1)          //相等时,为公共最长子序列输出
37     {
38         LCS(i-1,j-1,flag,a);cout<<a[i]<<" ";
39     }else if(flag[i][j]==2)
40     {
41          LCS(i-1,j,flag,a);
42     }else
43     {
44          LCS(i,j-1,flag,a);
45     }
46 }
47 int main()
48 {
49   int n,m;
50   cout<<"俩数组长度分别为"<<endl;
51   cin>>n>>m;
52   int a[n+1];
53   int b[m+1];
54   cout<<"输入"<<n<<"个数"<<endl;
55   for(int i=1;i<=n;i++)
56   {
57       cin>>a[i];
58   }
59    cout<<"输入"<<m<<"个数"<<endl;
60   for(int i=1;i<=m;i++)
61   {
62       cin>>b[i];
63   }
64
65   int *c[n+1],*flag[n+1];        //数组c[i][j],标记数组flag[i][j].
66  for(int i=0;i<n+1;i++)
67   {
68       c[i]=(int *)malloc((m+1)*sizeof(int));
69        flag[i]=(int *)malloc((m+1)*sizeof(int));
70   }
71   cout<<"最长公共子序列为"<<endl;
72   cout<<longque(m,n,a,b,c,flag)<<endl;  //求最长公共子序列长度
73   LCS(n,m,flag,a);                      //打印序列
74
75 }
时间: 2024-10-23 19:42:44

最长公共子序列计算及打印的相关文章

最长公共子序列-jobdu-1402(附带打印--undo)

jobdu-1042:Coincidence 时间限制:1 秒 内存限制:32 兆 题目描述: Find a longest common subsequence of two strings. 输入: First and second line of each input case contain two strings of lowercase character a-z. There are no spaces before, inside or after the strings. Le

最长公共子序列(lcs)

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)Output输出最长的子序列,如果有多个,随意输出1个.Sample Input abcicba abdkscab Sample Output abca题解:求最长公共子序列,并打印,先求出最长公共子序列,

最长公共子序列Lcs(打印路径)

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) Output 输出最长的子序列,如果有多个,随意输出1个. Input示例 abcicba abdkscab Output示例 abca #include <bits/stdc++.h> usin

动态规划之最长公共子序列(LCS)

tips : 本文内容是参考了很多著名博客和自己的思考得出的,如有不当欢迎拍砖. 先简单说一下动态规划 通俗地说:动态规划就是将一个可以划分为子问题的问题进行递归求解,不过动态规划将大量的中间结果保存起来, 不管它们是否会用得到,从而在后面的递归求解过程中可以快速求解.由此可以看得出来动态规划是一个以牺牲空间 为代价换取时间的算法. 对于最长公共子序列的题目不用多说,现在来分析一下LCS的动态规划解决思路: 一.首先先观察问题是否符合动态规划最明显的两个特征:最优子结构和重叠子问题 方便起见,以

一天一道算法题(4)---最长公共子序列

题目 给定两个字符串str1和str2,返回两个字符串的最长公共子序列 解析 本题是非常经典的动态规划问题,先来介绍求解动态规划表的过程.如果str1的长度为M,str2的长度为N,生成大小为M*N的矩阵dp,行数为M,列数为N.dp[i][j]的含义是str1[0..i]和str2[0..j]的最长公共子序列的长度.从左到右,再从上到下计算矩阵dp. 1.矩阵dp第一列即dp[0..M-1][0],dp[i][0]的含义是str1[0..i]与str2[0]的最长公共子序列的长度. 2.矩阵d

Algorithm --&gt; 最长公共子序列(LCS)

一.什么是最长公共子序列 什么是最长公共子序列呢?举个简单的例子吧,一个数列S,若分别是两个或多个已知序列的子序列,且是所有符合条件序列中最长的,则S称为已知序列的最长公共子序列. 举例如下,如:有两个随机数列,1 2 3 4 5 6 和 3 4 5 8 9,则它们的最长公共子序列便是:3 4 5. 最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为:子串是串的一个连续的部分,子序列则是从不改变

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

第十五章 动态规划——最长公共子序列

1.基本概念 一个给定序列的子序列就是该给定序列中去掉零个或者多个元素的序列.形式化来讲就是:给定一个序列X={x1,x2,……,xm},另外一个序列Z={z1.z2.……,zk},如果存在X的一个严格递增小标序列<i1,i2……,ik>,使得对所有j=1,2,……k,有xij = zj,则Z是X的子序列.例如:Z={B,C,D,B}是X={A,B,C,B,D,A,B}的一个子序列,相应的小标为<2,3,5,7>.从定义可以看出子序列直接的元素不一定是相邻的. 公共子序列:给定两个

算法设计 - LCS 最长公共子序列&amp;&amp;最长公共子串 &amp;&amp;LIS 最长递增子序列

出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的最长公共子串方法.最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度:还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn):空间也可以用其他方法优化成线性.3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn)