算法:最长公共子序列(输出所有最长公共子序列)
问题描述:给定两个序列,例如 X = “ABCBDAB”、Y = “BDCABA”,求它们的最长公共子序列的长度。
下面是求解时的动态规划表,可以看出 X 和 Y 的最长公共子序列的长度为4:
输出一个最长公共子序列并不难(网上很多相关代码),难点在于输出所有的最长公共子序列,因为 LCS 通常不唯一。
我们需要在动态规划表上进行回溯 —— 从c[m][n],即右下角的格子,开始进行判断:如果格子c[i][j]对应的X[i-1] == Y[j-1],则把这个字符放入 LCS 中,并跳入c[i-1][j-1]中继续进行判断;如果格子c[i][j]对应的 X[i-1] ≠ Y[j-1],则比较c[i-1][j]和c[i][j-1]的值,跳入值较大的格子继续进行判断;如果出现c[i-1][j]等于c[i][j-1]的情况,说明最长公共子序列有多个,故两边都要进行回溯(这里用到递归)。直到 i 或 j 小于等于零为止,倒序输出 LCS 。
从上图的红色路径显示,X 和 Y 的最长公共子序列有 3 个,分别为 “BDAB”、“BCAB”、“BCBA”。
C++代码:
#include<bits/stdc++.h>
using namespace std;string X ;
string Y ;
vector<vector<int> > c; // 动态规划表
set<string> lcs; // set保存所有的LCSint lcs_length(int m, int n)
{// 表的大小为(m+1)*(n+1)c = vector<vector<int> >(m+1,vector<int>(n+1));for(int i=0; i<m+1; ++i){for(int j=0; j<n+1; ++j){// 第一行和第一列置0if (i == 0 || j == 0)c[i][j] = 0;else if(X[i-1] == Y[j-1])c[i][j] = c[i-1][j-1] + 1;elsec[i][j] = max(c[i-1][j], c[i][j-1]);}}return c[m][n];
}void lcs_print(int i, int j, string lcs_str)
{while (i>0 && j>0){if (X[i-1] == Y[j-1]){lcs_str.push_back(X[i-1]);
// cout<<X[i-1]<<endl;--i;--j;}else{if (c[i-1][j] > c[i][j-1])--i;else if (c[i-1][j] < c[i][j-1])--j;else{lcs_print(i-1, j, lcs_str);lcs_print(i, j-1, lcs_str);return;}}}
// cout<<lcs_str<<endl;reverse(lcs_str.begin(),lcs_str.end());lcs.insert(lcs_str);
}int main()
{cin>>X>>Y;int m = X.length();int n = Y.length();int length = lcs_length(m, n);cout << "The length of LCS is " << length << endl;string str;lcs_print(m, n, str);set<string>::iterator it = lcs.begin();for( ; it!=lcs.end(); it++)cout << *it << endl;return 0;
}
运行效果:
算法:最长公共子序列(输出所有最长公共子序列)相关推荐
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...
作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...
- 实验三、最长公共子序列(输出所有最长公共子序列)
实验3.最长公共子序列 问题描述与实验目的: 序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2,3,5,7>. ...
- 【恋上数据结构】动态规划(找零钱、最大连续子序列和、最长上升子序列、最长公共子序列、最长公共子串、0-1背包)
动态规划(Dynamic Programming) 练习1:找零钱 找零钱 - 暴力递归 找零钱 - 记忆化搜索 找零钱 - 递推 思考题:输出找零钱的具体方案(具体是用了哪些面值的硬币) 找零钱 - ...
- nyoj 36 最长公共子序列 dp问题最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共
最长公共子序列 时间限制: 3000 ms | 内存限制: 65535 KB 难度: 3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称 ...
- 20190501-编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串...
题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ...
- java查询字符串公共前缀_No.14 最长公共前缀(Java)
题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 输入: ["flower","flow&qu ...
- 最长回文子串与最长回文子序列
文章目录 最长回文子串与最长回文子序列 最长回文子串 题目描述 dp解法 从中心扩展 马拉车算法 最长回文子序列 题目描述 dp 解法 递归思想 最长回文子串与最长回文子序列 最长回文子串 LeetC ...
- 最长递增子序列 子串_最长递增奇偶子序列
最长递增子序列 子串 Problem statement: 问题陈述: Given a sequence of numbers you have to find out the length of t ...
- 二叉树-求第一条最长路径长度并输出路径
求第一条最长路径长度并输出路径 算法思想 利用递归遍历思想,先求出二叉树最长路径也就是当前树的高度 再调用求路径长度的函数判断指针走向输出路径 int LongestPath(BiTree *T){ ...
最新文章
- 【怎样写代码】工厂三兄弟之工厂方法模式(一):问题案例
- msdn关于Visual C++ 编译器选项的说明
- python钻石数据分析_数据分析该用什么工具?
- LeetCode 102. 二叉树的层次遍历(BFS)
- 即时通讯应用战争开打,到底谁能最终定义我们的交流方式?
- 【298天】每日项目总结系列036(2017.11.30)
- Slam(即时定位与地图构建)
- C语言程序设计实验报告——实验五
- 关于一个博客系统的 整体架构与技术
- mysql 查询本月所有天数统计对应数据
- nltk包下载慢的解决方案(总结)
- 程序员在群里“匿名”骂老板,第二天被开除,聊天记录曝光
- BFS-BZOJ-1615-[Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机
- 【权限设计】最好的权限设计,是先区分功能权限和数据权限
- 【综述专栏】马毅沈向洋曹颖最新AI综述火了!
- 【性能测试】性能测试的概念和术语介绍 性能测试分类(了解每种测试的目的)
- 社交网络里的高级钓鱼攻击
- 专题:解析WINDOWS命令行下的的磁盘清理程序CLEANMGR
- (GPS移植三部曲)Linux下移植GPS应用程序之常见问题的分析与解决方法之三
- 3.3 设银行定期存款的年利率rate为2.25%,已知存款期为n年,存款本金为capital元,试编程计算并输出n年后的本利之和deposit
热门文章
- Google在线翻译工具:Translatium for Mac支持big sur
- VMware 8.0 安装 FC5 的VMware tools
- eclipse中import existing projects into workspace和open projects from file systems分别有什么用?
- 广西铁路局计算机类待遇怎么样,南宁铁路局月薪待遇 如何进入铁路工作
- linux中ifconfig无法显示ip地址
- 剪辑技巧,全部视频添加封面图片后保存在哪
- Unity游戏开发——向量运算(点乘和叉乘)
- 专业技术计算机应用能力考试题库,全国专业技术人员计算机应用能力考试题库-Excel,Word,XP...
- 关于edu邮箱收不到国外投稿邮件的解决办法
- 【淘宝】从开店到运营 - 开店前期知识(天猫、淘宝店铺介绍)