LCS最大公共子序列【转载】
在两个字符串中,有些字符会一样,可以形成的子序列也有可能相等,因此,长度最长的相等子序列便是两者间的最长公共字序列,其长度可以使用动态规划来求。
以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。
借用《算法导论》中的推导图:
创建 DP数组C[][];
图中的空白格子需要填上相应的数字(这个数字就是c[i][j]的定义,记录的LCS的长度值)。填的规则依据递归公式,简单来说:如果横竖(i,j)对应的两个元素相等,该格子的值 = c[i-1,j-1] + 1。如果不等,取c[i-1,j] 和 c[i,j-1]的最大值。首先初始化该表:
然后,一行一行地从上往下填:
S1的元素3 与 S2的元素3 相等,所以 c[2,1] = c[1,0] + 1。继续填充:
S1的元素3 与 S2的元素5 不等,c[2,2] =max(c[1,2],c[2,1]),图中c[1,2] 和 c[2,1] 背景色为浅黄色。
继续填充:
中间几行填写规则不变,直接跳到最后一行:
至此,该表填完。根据性质,c[8,9] = S1 和 S2 的 LCS的长度,即为5。
得到公式
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int MAXN = 1005;
int DP[MAXN][MAXN];
int main()
{
string a;
string b;
while(cin >> a >> b)
{
int l1 = a.size();
int l2 = b.size();
memset(DP, 0, sizeof(DP));
for(int i = 1; i <= l1; i++)
for(int j = 1; j <= l2; j++)
if(a[i - 1] == b[j - 1])
DP[i][j] = max(DP[i][j], DP[i - 1][j - 1] + 1);
else
DP[i][j] = max(DP[i][j - 1], DP[i - 1][j]);
printf("%d\n", DP[l1][l2]);
}
return 0;
}
当得到完整的DP表之后,我们可以通过倒推来得到相应的子序列
S1和S2的最LCS并不是只有1个,本文并不是着重讲输出两个序列的所有LCS,只是介绍如何通过上表,输出其中一个LCS。
我们根据递归公式构建了上表,我们将从最后一个元素c[8][9]倒推出S1和S2的LCS。
c[8][9] = 5,且S1[8] != S2[9],所以倒推回去,c[8][9]的值来源于c[8][8]的值(因为c[8][8] > c[7][9])。
c[8][8] = 5, 且S1[8] = S2[8], 所以倒推回去,c[8][8]的值来源于 c[7][7]。
以此类推,如果遇到S1[i] != S2[j] ,且c[i-1][j] = c[i][j-1] 这种存在分支的情况,这里请都选择一个方向(之后遇到这样的情况,也选择相同的方向)。
第一种结果为:
这就是倒推回去的路径,棕色方格为相等元素,即LCS = {3,4,6,7,8},这是其中一个结果。
如果如果遇到S1[i] != S2[j] ,且c[i-1][j] = c[i][j-1] 这种存在分支的情况,选择另一个方向,会得到另一个结果。
即LCS ={3,5,7,7,8}。
在倒推时,如果s1[i] == s2[j] 就跳转到c[i - 1][j - 1],如果s1[i] != s1[j], 就向前找或向上找(只能一个方向)
PS:在代码中和解说中代码细节有所不同,在解说图中s从下标1开始,在代码中从下标0开始。
---------------------
作者:someone_and_anyone
来源:CSDN
原文:https://blog.csdn.net/someone_and_anyone/article/details/81044153
转载于:https://www.cnblogs.com/macren/p/11067704.html
LCS最大公共子序列【转载】相关推荐
- 最大公共子序列、子串、可重叠重复子串
最长公共子序列 寻找两个给定序列的子序列,该子序列在两个序列中以相同的顺序出现,但是不必要是连续的 举例:X=ABCBDAB,Y=BDCABA.序列 BCA是X和Y的一个公共子序列,但不是X和Y的最长 ...
- DP-最大递增子序列与最大递增子数组; 最大公共子序列与最大公共子数组。
这些都是动态规划的题目. 解决动态规划的题目有个重点就是找出递推方程. 但问题在于递归方程不是那么好找的.如何恰当的定义目标函数是最大的难点. 如最大公共子数组中可定义A[m][n]为以A[m] B[ ...
- 最大公共字符串,最大公共子序列,编辑距离,myers等算法
1 前言 这个4个算法比较相似,并且有以下相同点和不同点 2 异同点 以str1 = "ABCDEF" , str2="ZABCDZE" 为例 相同点: 1.都 ...
- 递归法:求两个串的最大公共子序列的长度
问题:求两个串的最大公共子序列的长度 举例: 子串: abcgxs 与sabxfh 其最大公共子序列的为abx,长度为3 public class Zixulie {public static int ...
- buct oj 最大公共子序列问题
问题 B 最大公共子序列问题 时间限制: 1 Sec 内存限制: 128 MB [提交] 题目描述 对序列X=(x1, x2, .., xm),定义其子序列为(xi1, xi2, .., xik), ...
- 穷举法求最大公共子序列C语言,算法--最长公共子序列(LongestCommon Subsequence, LCS)...
定义: 两个字符串共有的最长的子序列(可不连续),最长公共字符串(Longest CommonSubstring)是两个字符串共有的最长的连续字符串. 方法:穷举法,动态规划 动态规划法的简介: &l ...
- 动态规划---实现输出最大公共子序列的长度以及输出最大子字符串(java语言描述)
参考博客地址:http://blog.csdn.NET/biangren/article/details/8038605 http://blog.csdn.net/njr465167967/artic ...
- python实现最大公共子序列
介绍 子序列和子串的意思不一样,如下图所示,子序列不要求连续,只需要在给定序列中出现过,并且相对顺序一致.而子串需要连续. 图片来自动态规划 最长公共子序列 过程图解 最长公共子序列(LCS): 同时 ...
- 快速了解日志概貌,详细解读13种日志模式解析算法
云智慧 AIOps 社区是由云智慧发起,针对运维业务场景,提供算法.算力.数据集整体的服务体系及智能运维业务场景的解决方案交流社区.该社区致力于传播 AIOps 技术,旨在与各行业客户.用户.研究者和 ...
最新文章
- 如何使用React提前三天计划
- python glob 模块 map函数
- 人脸分割 人脸解析 源码推荐
- c语言编写经验逐步积累3
- [C++STL]常用拷贝和替换算法
- java 百度账号注册界面_基于百度AI使用H5实现调用摄像头进行人脸注册、人脸搜索功能(Java)...
- Qt文档阅读笔记-Broadcast Sender Example与Broadcast Receiver Example解析
- java求n个分数之和_N个快速提升分数的学习方法
- html编辑四则运算,前端四则运算验证
- MyBatis3源码解析(6)TypeHandler使用
- Android 10正式版发布,支持5G和折叠屏设备
- 51单片机程序0到60计数个位逢5和6不显示,十位逢1不显示http://www.51hei.com/bbs/mcu-h24-1.html
- MATLAB排列组合计算
- 拆解下3个大厂(抖音,滴滴,拼多多)的数据分析案例
- 人像抠图软件哪个好?这些软件助你实现人像抠图
- 大数据就业前景,分析的太到位了
- SolidPlant材料清单
- 70条正则表达式的整理汇总
- 天正自定义填充图案怎么添加_天正填充图案 图层管理 文件
- 青蛙现象、鳄鱼法则、鲇鱼效应、羊群效应、刺猬法则、手表定律、破窗理论、二八定律、木桶理论、马太效应
热门文章
- HTML5和Flash——如何选择合适的工具
- memcachedb 加 memcached engine无法提高 示例检索的查询速度
- 老师学python可以干嘛-你都用 Python 来做什么?
- python100行代码程序-100行python代码,轻松完成贪吃蛇小游戏
- python学了可以干什么-学了Python都能干什么,哪个最赚钱?
- python怎么安装第三方库-怎样安装Python的第三方库
- 笨方法学python3-笨办法学python3 pdf下载|
- python3下载安装配置-Linux 安装python3.7.3
- python打开指定文件-python打包压缩、读取指定目录下的指定类型文件
- python推荐入门书籍-学python入门看什么书