最长公共子序列
来源:互联网 发布:男士护肤吧 淘宝店铺 编辑:程序博客网 时间:2024/06/05 06:37
一、最长公共子序列算法基本思想
最长公共子序列是基于动态规划的思想。
最长公共子序列,英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。而最长公共子串(要求连续)和最长公共子序列是不同的(摘自百度百科)
我们可以分三个方面思考这样个问题:
1.如果x序列的最后一个元素和y序列的最后一个元素相同,那么这个元素必定是最长公共子序列的最后一个元素。
2.如果x序列和y序列的最后一个元素不同,那么问题就推给除了最后一个元素的x序列和完整y序列这两个序列的最长公共子序列(记为A),以及完整的x序列和除了最后一个元素的y序列这两个序列的最长公共子序列(记为B),max{A,B}就是原问题的解。
3.重复2步骤,递归下去,一直到x序列为空,或者y序列为空。
二、最长公共子序列的数据结构
c[i][j] 二维数组: 表示x从1到i的子序列和y从1到j的子序列的最长公共子序列。
b[i][j] 二维数组:表示x从1到i的子序列和y从1到j的子序列的最长公共子序列是由哪种情况下获得的。
value 1: 表示当xi == yi 字符的时候获得一个最长公共子序列的元素
value 2: 表示问题推给了x[1...i-1] 和 y[1...j]的最长公共子序列
value 3: 表示问题推给了x[1...i] 和 y[1...j-1]的最长公共子序列
三、最长公共子序列过程图解
四、算法源代码
#include <cstdio>//序列x以及x的长度,字符串前面的空格是来填充的//好让字符串首字母从下标1开始char x[] = " ABCBDAB";int lenx = 7;//序列y以及y的长度char y[] = " BDCABA";int leny = 6;//c[i][j]表示长度为i的x序列//和长度为j的y序列的最大公共子序列int c[8][7];//记录c[i][j]的值是由哪个子问题产生的int b[8][7];//计算最长公共子序列的函数//并且记录了最长公共子序列int lcsLength();//构建最长公共子序列void lcs(int i, int j);int main(){ printf("%d\n",lcsLength()); lcs(lenx, leny); return 0;}int lcsLength(){ //如果x为空序列那么无论y取多长,x,y的最大公共子序列一定为0 for (int i = 1; i<=lenx; i++) c[i][0] = 0; //如果y为空序列那么无论x取多长,x,y的最大公共子序列一定为0 for (int i = 1; i<=leny; i++) c[0][i] = 0; for (int i=1;i<=lenx;i++){ for (int j=1; j<=leny; j++) { //如果长度为i的x序列和长度为j的y序列的最后一个字符相同 //那么最大公共子序列就是c[i-1][j-1]+1 if(x[i] == y[j]){ c[i][j] = c[i-1][j-1]+1; b[i][j] = 1; //用1标记表示长度为i的x序列 //长度为j的y序列中最后一个字符是相同的 //如果不等那么c[i][j] = max{c[i-1][j] , c[i][j-1]} }else if(c[i-1][j]>=c[i][j-1]){ c[i][j] = c[i-1][j]; b[i][j] = 2; }else{ c[i][j] = c[i][j-1]; b[i][j] = 3; } } } return c[lenx][leny];}//通过b数组记录的信息构建最长公共子序列void lcs(int i,int j){ if(i==0||j==0) return; if (b[i][j] == 1) { lcs(i-1,j-1); printf("%c",x[i]); }else if(b[i][j] == 2){ lcs(i-1,j); }else{ lcs(i,j-1); }}
0 0
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 中断处理
- jsp 页面链接(注解:指a标签的超链接)乱码问题及其解决办法
- 第十五周项目一
- C#中的Dictionary字典类介绍
- Android Fragment完全解析,关于碎片你所需知道的一切
- 最长公共子序列
- jqplot内存泄漏、内存不断增加管理ajax
- dwz+nutz+xheditor 论坛输入框上传图片
- Python爬虫框架Scrapy实战教程---定向批量获取职位招聘信息
- sql 生成树型样式
- js跳出循环:break 、continue 、return
- YAHOO的YUI框架
- 浅谈C/C++内存泄漏及其检测工具
- Structs2 <s:date> <s:debug> <s:property>说明