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
LCS最大公共子序列【转载】的更多相关文章
- python3 lcs 最大公共子序列
抛出问题: 假定字符串 s1 = 'BDCABA', s2 = 'ABCBDAB',求s1和s2的最大公共子序列. 问题分析: 我们想要求出s1和s2的最大公共子序列,我们可以用c(i,j)表示s1( ...
- LCS最大公共子序列问题
在生物应用中,经常需要比较两个(或多个)不同生物体的DNA, 例如:某种生物的DNA可能为S1=ACCGGTCGAGTGCGCGGAAGCCGGCCGAA, 另一种生物的DNA可能为S2=GTCGTT ...
- 动态规划之LCS(最大公共子序列)
#include <stdio.h> #include <string.h> int b[50][50]; int c[50][50]; int length = 0; voi ...
- Poj1159 Palindrome(动态规划DP求最大公共子序列LCS)
一.Description A palindrome is a symmetrical string, that is, a string read identically from left to ...
- Advanced Fruits (最大公共子序列的路径打印)
The company "21st Century Fruits" has specialized in creating new sorts of fruits by trans ...
- hdu 1243 反恐训练营(dp 最大公共子序列变形)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1243 d[i][j] 代表第i 个字符与第 j 个字符的最大的得分.,, 最大公共子序列变形 #inclu ...
- spoj Longest Common Substring (多串求最大公共子序列)
题目链接: https://vjudge.net/problem/SPOJ-LCS 题意: 最多10行字符串 求最大公共子序列 数据范围: $1\leq |S| \leq100000$ 分析: 让他们 ...
- POJ - 2250 Compromise (LCS打印序列)
题意:给你两个单词序列,求出他们的最长公共子序列. 多组数据输入,单词序列长度<=100,单词长度<=30 因为所有组成LCS的单词都是通过 a[i] == b[j] 更新的. 打印序列的 ...
- Common Subsequence 最大公共子序列问题
Problem Description A subsequence of a given sequence is the given sequence with some elements (poss ...
随机推荐
- React之组件小析
组件就是标签,html的标签某种角度讲就是组件. index.js是项目的入口文件. react中大写字母开头的都是组件. App.js就是一个组件. ReactDOM会将组件内容,渲染到页面当中. ...
- ORA-00600: internal error code, arguments: [6749], [3], [12602196]
环境信息:Linux5.8 oracle10.2.0.4 问题现象: 现象1:alert日志有大量下面的错误信息: Wed Aug 27 21:01:27 2014Errors in file /u0 ...
- 分享知识-快乐自己:Excel快速导入Oracle 数据库
需求: oracle 数据库有一个student表,现有一个excel表:student.xlsx,需导入oracle数据库student表中. student表的拥有者是c##MLQ1 密码为:x ...
- 几个网络模型的示例代码(BlockingModel、OverlappedModel、WSAEventSelect、CompletionRoutine)..c++
作者的blog:猪)的网络编程世界 几个网络模型的示例代码代码包括了下面几个模型的示例:BlockingModel(阻塞模式).OverlappedModel(基于事件的重叠I/O).WSAEvent ...
- 几个重要的 ASM Disk Groups 参数
几个重要的Disk group 属性: 1. ACCESS_CONTROL.ENABLED该属性用来控制某个disk group 上ASM FILE Access Control. 该参数有2个值:t ...
- CF 949D Curfew——贪心(思路!!!)
题目:http://codeforces.com/contest/949/problem/D 有二分答案的思路. 如果二分了一个答案,首先可知越靠中间的应该大约越容易满足,因为方便把别的房间的人聚集过 ...
- boost::function 通过boost::bind调用类成员函数
1. 首先引用boost::function和boost::bind的头文件和库: #include "boost/bind.hpp" #include "boost/f ...
- CentOS下安装配置Samba服务器
0 环境介绍 VMWARE12下安装的CENTOS7虚拟机.宿主机为WIN7. 1 离线安装 费了九牛二虎之力,下载各种依赖,还是有问题,转向在线安装. 2 在线安装 虚拟机采用默认的配置: 其次,网 ...
- jsonp实现数据跨域请求
1.我们知道,哪怕跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是可以无条件执行的. 远程服务器remoteserver.com根目录下有个remote.js文件代码如下: al ...
- PHP生成唯一的订单号
记:之前面试的时候被面试官问过简历项目中的订单号我是什么规则生成的,我牛逼吹过头了,乱说了一通,靠!今天在公司的项目中订单号生成,好奇,看了下,就是网上的这种而已. * * uniqid - 官方是这 ...