算法实践--最长公共子序列(Longest Common Subsquence)
什么是最长公共子序列
X=ACCG
Y=CCAGCA
长度为1的公共子序列: {A} {C} {G}
长度为2的公共子序列:{AC} {CC} {CG} {AG}
长度为3的公共子序列:{ACG}
长度为4的公共子序列
最长公共子序列即为 {ACG}
问题:长度为N和M的两个序列如何求他们的最长公共子序列?
X = ACCGGGTTACCGTTTAAAACCCGGGTAACCT
Y = CCAGGACCAGGGACCGTTTACCAGCCTTAAACCA
简单算法
for (int i=N; i>0; --i) {
找到X所有长度为i的子序列;
找到Y所有长度为i的子序列;
如果存在公共子序列则终止
}
复杂度O(2^N)
动态规划算法
定义C[i][j]为序列X[i..i]和Y[1..j]的最长子序列的长度
C[i][0]和C[0][j]==0
递推公式
C[i][j]=C[i-1][j-1]+1, X[i]==Y[j]
C[i][j]=MAX(C[i-1][j], C[i][j-1]), X[i]!=Y[j]
C++实现
template<typename T>
void prtM(vector< vector<T> >& arr, string msg = "") {
cout << msg << " " << endl;
for (auto i: arr) {
for (auto j: i) {
cout << j << " ";
}
cout << endl;
}
cout << endl;
} template <typename T>
void prt(vector<T>& arr, string msg = "") {
cout << msg << " ";
for (auto i: arr) {
cout << i << " ";
}
cout << endl;
} void prt_LCS(vector< vector<char> >& S, string& X, int i, int j) { // 递归调用
//cout << "i=" << i << " j=" << j << " " << S[i][j] << endl;
if (i== || j == )
return;
if ('s' == S[i][j]) {
prt_LCS(S, X, i-, j-);
cout << X[i];
} else if ('j' == S[i][j]) {
prt_LCS(S, X, i, j-);
} else {
prt_LCS(S, X, i-, j);
}
} void calc_LCS(string& X, string& Y) {
cout << "X: " << X << endl;
cout << "Y: " << Y << endl; vector< vector<int> > C; // 序列X[0..i] and Y[0..j]的公共子序列的长度
vector< vector<char> > S; //最长公共子串的位置
for (int i=; i<X.size(); i++) {
C.push_back( vector<int>(Y.size()) );
S.push_back( vector<char>(Y.size()) );
} for (int i=; i<X.size(); i++)
C[i][] = ;
for (int j=; j<Y.size(); j++)
C[][j] = ; for (int i=; i<X.size(); i++)
for (int j=; j<Y.size(); j++) {
if (X[i] == Y[j]) {
C[i][j] = C[i-][j-] + ;
S[i][j] = 's'; // 相同,可以打印
} else if ( C[i][j-] > C[i-][j] ) {
C[i][j] = C[i][j-];
S[i][j] = 'j'; //Y的最后一个可以去掉,不影响LCS
} else {
C[i][j] = C[i-][j] ;
S[i][j] = 'i'; //X的最后一个可以去掉,不影响LCS
}
} prtM(C);
prtM(S);
prt_LCS(S, X, X.size()-, Y.size()-);
cout<< endl;
} int main() { string S1 = " ACCGGGTTAC"; // 为了方便表示,忽略第一个字符
string S2 = " AGGACCA"; calc_LCS(S1, S2); return ;
}
算法实践--最长公共子序列(Longest Common Subsquence)的更多相关文章
- 算法实践--最长递增子序列(Longest Increasing Subsquence)
什么是最长递增子序列(Longest Increasing Subsquence) 对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5 ...
- 最长公共子序列(Longest common subsequence)
问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子序列.(子序列中的字符不要求连续) 这道题可以 ...
- 算法练习——最长公共子序列的问题(LCS)
问题描述: 对于两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列.X Y 各自字符串有顺序,但是不一定需要相邻. 最长公共子串(Longest Common Subst ...
- 最长公共子串(Longest common substring)
问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子串.(子串中的字符要求连续) 这道题和最长公共 ...
- Java实现 蓝桥杯VIP 算法提高 最长公共子序列
算法提高 最长公共子序列 时间限制:1.0s 内存限制:256.0MB 问题描述 给定两个字符串,寻找这两个字串之间的最长公共子序列. 输入格式 输入两行,分别包含一个字符串,仅含有小写字母. 输出格 ...
- 【算法】最长公共子序列(nlogn)
转载注明出处:http://blog.csdn.net/wdq347/article/details/9001005 (修正了一些错误,并自己重写了代码) 最长公共子序列(LCS)最常见的算法是时间复 ...
- ACM/ICPC 之 最长公共子序列计数及其回溯算法(51Nod-1006(最长公共子序列))
这道题被51Nod定为基础题(这要求有点高啊),我感觉应该可以算作一级或者二级题目,主要原因不是动态规划的状态转移方程的问题,而是需要理解最后的回溯算法. 题目大意:找到两个字符串中最长的子序列,子序 ...
- 利用后缀数组(suffix array)求最长公共子串(longest common substring)
摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其 ...
- [Swift]LeetCode14. 最长公共前缀 | Longest Common Prefix
Write a function to find the longest common prefix string amongst an array of strings. If there is n ...
随机推荐
- 网络(socket)编程
一.网络协议 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构(互联网中处处是C/S架构):B/S架构也是C/S架构的一种,B/S是浏览器/服务器 C/S架构与socket的关系: ...
- vue-router中query和params传参(接收参数)以及$router、$route的区别
query传参: this.$router.push({ path:'/...' query:{ id:id } }) 接收参数:this.$route.query.id params传值: 传参: ...
- 【转载】koa相关知识(来自官网)
什么是Koa? koa 是由 Express 原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的 Web 框架.使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重 ...
- Go程序设计
01 Go基础特性&独有特性
- quartz.net的使用
Quartz.NET简介 Quartz.NET作业调度框架是伟大组织OpenSymphony开发的quartz scheduler项目的.net延伸移植版本. Quartz.NET是一个开源的作业调度 ...
- jquery的一个小扩展,读取URL里的参数
/* *扩展jquery的功能: *读取url中参数的功能,方法的参数是要获取的URL里键; *使用前要先导入jquery.js文件. * */ (function ($) { $.getUrlPar ...
- 【转载】关于nginx以及内核参数的配置
nginx应用总结(2)--突破高并发的性能优化 原文地址:https://www.cnblogs.com/kevingrace/p/6094007.html 在日常的运维工作中,经常会用到ngin ...
- redis-sentinel主从复制高可用
Redis-Sentinel Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端 ...
- VS遇到的问题记录
Q:id为xxxx的进程当前未运行 A:将端口改掉.
- LNMP(二)
第二十一课 LNMP(二) 目录 一.默认虚拟主机 二.Nginx用户认证 三.Nginx域名重定向 四.Nginx访问日志 五.Nginx日志切割 六.静态文件不记录日志和过期时间 七.Nginx防 ...