LCS(最长公共子序列)递归/动态规划
思路来自邓俊辉—数据结构(C++)
2019/08/23
递归思路
对于序列A[0,n] 和B[0,m], LCS(A, B)有三种情况:
0)若n = -1或m = -1,则取作空序列(" ");
1)若A[n] == ‘X’ == B[m],则取作LCS( A[0, n) , B[0, m) + ‘X’;
2)若A[n] != B[m],则在LCS( A[0, n], B[0, m) ) 与LCS( A[0, n), B[0, m] ) 中取更长者;
代码1.0(返回重复个数)
int LCS(const string& a, const string& b){ //返回公共子序列的字符个数int n = a.length();int m = b.length();if(n == 0 || m ==0) //情况1return 0;else if (a.back() == b.back()) //情况2return LCS(a.substr(0, n - 1), b.substr(0, m-1)) + 1;else //情况3return max(LCS(a.substr(0, n), b.substr(0, m - 1)), //取两者最大值LCS(a.substr(0, n - 1), b.substr(0, m)));
}
2019/08/24
代码1.1(返回重复字符串)
string max(string A, string B){ //返回更长的字符串return A.length() > B.length() ? A : B;
}string LCS(string A, string B){int len_A = A.length();int len_B = B.length();if( len_A == 0 || len_B == 0) //情况1return "";else if (A.back() == B.back()) //情况2return LCS(A.substr(0, len_A - 1), B.substr(0, len_B - 1)) + A.back();else //情况3return max(LCS(A.substr(0, len_A), B.substr(0, len_B - 1)),LCS(A.substr(0, len_A - 1), B.substr(0, len_B)));
}
动态规划思路
1.为什么使用动态规划:采用动态规划时,并不需要去一 一 计算那些重叠了的子问题。或者说:用了动态规划之后,有些子问题 是通过 “查表“ 直接得到的,而不是重新又计算一遍得到的。(类似Fib数列用递归方法计算时会重复计算部分项)
2.如何得到dp数组:
设序列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的最长公共子序列。
其中Xm-1=<x1, x2, …, xm-1>,Yn-1=<y1, y2, …, yn-1>,Zk-1=<z1, z2, …, zk-1>。
简而言之一张图(注意图有一处错误:i=0 或 j = 0时,C[i, j]不一定是0):
3.如何利用得到dp二维数组得到公共子序列:若两序列A[i]的元素和B[i]的元素相等,那么最长公共子序列为A[0, i -1], B[0, j - 1]的最长公共子序列的值加1。否则分别是A[0, i- 1], B[0 ,j] 或者A [0, i - 1], B[0, j ]的最长公共子序列的较大值。
代码2.0(动态规划)
int** LCS(const string a, const string b){ int la = a.length(); int lb = b.length();//创建动态二维数组 int **dp = new int *[la];for(int i = 0; i < la; ++i)dp[i] = new int[lb];//设置左、上边界的值for(int i = 0; i < lb; ++i) //上if(a[0] == b[i])dp[0][i] = 1;else dp[0][i] = 0;for(int i = 0; i < la; ++i) //左if(b[0] == a[i])dp[i][0] = 1;else dp[i][0] = 0;int maxium = 0; //记录最大值for(int i = 1; i < la; ++i) //得到字符串a、b第i、j个字符for(int j =1; j < lb; ++j){if(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]);if(dp[i][j] > maxium)maxium = dp[i][j];}string result = ""; //保存公共子序列int k = la, t = lb;while (maxium >= 0) {if (a[k] == b[t]) {result += a[k];--k; --t;--maxium;}else {if (dp[k][t - 1] >= dp[k - 1][t]) --t;else --k;}}reverse(result.begin(), result.end()); //头文件<algorithm>cout << result << endl;return dp;//主函数一定要记得销毁二维动态数组所占的空间}
tip :创建、销毁动态二维数组
//创建动态二维数组
int **dp = new int *[la];
for(int i = 0; i < la; ++i)dp[i] = new int[lb];
//销毁动态二维数组
for(int i = 0; i < la; ++i){delete[] dp[i];dp[i] = NULL;
}
delete[] dp;
dp = NULL;
LCS(最长公共子序列)递归/动态规划相关推荐
- 算法设计 - LCS 最长公共子序列最长公共子串 LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...
- LCS最长公共子序列和LIS最长上升子序列——例题剖析
一.LCS最长公共子序列 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我) longest comment subsequence 模板题 longe ...
- LCS(最长公共子序列)及其O(n)空间优化,O(nlogn)时间复杂度优化
LCS(最长公共子序列)及其O(n)空间优化,O(nlogn)时间复杂度优化 n^2 的版本 int LCS_n_2(vector<char> &a,vector<char& ...
- 【BZOJ2423】最长公共子序列(动态规划)
[BZOJ2423]最长公共子序列(动态规划) 题面 BZOJ 洛谷 题解 今天考试的时候,神仙出题人\(fdf\)把这道题目作为一个二合一出了出来,我除了orz还是只会orz. 对于如何\(O(n^ ...
- 最长公共子序列php,动态规划(最长公共子序列LCS)
概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...
- 动态规划求解LCS最长公共子序列问题c++
文章目录 求最长公共子序列 最长公共子序列问题 刻画最长公共子序列的特征 递归公式 C++代码 求最长公共子序列长度 打印任意一组最长公共子序列 模板题 求最长公共子序列 最长公共子序列问题 (Lon ...
- 算法知识之最长公共子序列问题(动态规划)
最近朋友让帮做个关于动态规划的最长公共子序列的问题,翻看以前的笔记并完成该题后,顺便写这样一篇文章,希望对大家有所帮助,同时也帮助自己回顾该知识点. 一.最长公共子序列的定义 子序列:若给定序列X={ ...
- 【算法设计与分析】最长公共子序列问题 动态规划算法 超详细
最长公共子序列问题描述 注意:最长公共子序列不一定是连续序列. 例如:"ASAFAGAHAJAK"与"AAAAAAA"的最长公共子序列为:AAAAAA 公共子序 ...
- LCS/最长公共子序列/最长公共子串 实现 Python/Java
参考 http://blog.csdn.net/u012102306/article/details/53184446 http://blog.csdn.net/hrn1216/article/det ...
- 2017蓝桥杯B组:最长公共子序列(动态规划详解(配图))
最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少. 比如:"abcdkkk" 和"baabcdadabc", 可以找到的最长的公共子串 ...
最新文章
- 推荐系统学习(一)推荐系统分类与基本流程
- 年轻人“颜值消费”崛起 分期乐联手屈臣氏发力95后美妆护理市场
- Atitit react 详细使用总结 绑定列表显示 attilax总结 1. 前言	1 1.1. 资料数量在百度内的数量对比	1 1.2. 版本16 v15.6.1	1 1.3. 引入js	2
- 汽车方向盘电子助力转向器如何接线_案例 | 看3D打印如何助力汽车电子连接器模具冷却水路的设计优化...
- Heartbeat介绍
- 【节日快乐】圣诞元旦在即,你准备好怎么营销了吗?
- 隔离变压器不触电原因
- Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)
- 混沌工程——各大厂实践分享汇总(上篇)
- 网站风格变黑白的方法,用css或javascript方法将网站改为灰色
- 小白学数据 | 除了计算大姨妈周期,时间序列分析还有什么用
- uniapp:uni.chooseImage、uni.uploadFile,选择图片,上传图片
- 大学物理简明教程全书思维导图
- Tensorlow-gpu安装win7+Anaconda
- IE安全系列:脚本先锋(2)
- 多边形轮廓 等距离外扩
- Salesforce的核心密码
- 云原生时代---带你了解火爆的Quarkus技术
- python基础入门(三)
- 秦嘉哲:11.9黄金原油晚间行情趋势分析及欧美盘最新操作建议
热门文章
- 【毕设教程】python区块链实现 - proof of work工作量证明共识算法
- MyDLNote-High-Resolution: CooGAN: 协同GAN网络,高分辨率面部属性的高效记忆框架
- python根据关键词实现信息检索推荐(使用深度学习算法)
- 使用 npm shrinkwrap 来管理项目依赖
- php 数独计算器,问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字_题来了...
- 最全空降Golang资料补给包(满血战斗),包含文章,书籍,作者论文,理论分析,开源框架,云原生,大佬视频,大厂实战分享ppt
- 【运动蓝牙耳机选择】运动蓝牙耳机怎么选 哪种无线蓝牙运动耳机适合你
- 音视频开发之Android端native层播放音频三种方式
- Excel如何输入负数
- 我的第一堂职业素质课