今天看了七月在线算法课。再一次认识了LCS,现在整理记录:

LCS(Longest Common Subsequence)最长公共子序列。

一个序列S任意删除若干个字符得到新序列T,那么T叫做S的子序列。

两个序列X和Y的公共子序列中,长度最长的那个叫X和Y的最长公共子序列。

例如:

字符串13455和245576的最长公共子序列为455.

字符串acdfg和adfc的最长公共子序列为adf.

注意:这里要区别最长公共子串LCS(Longest Common Substring),这个要求的是字符串必须连续。

这里偷懒,直接拿了老师的PPT。记好下面的记号。

下面就进行LCS解法的探索:

当x=y的时候:

然后我们就能得到:

此处的意思就是:当两个子序列中结尾字符是相等的,那么最长的子序列就肯定是这个相等值+前面的的最长长度了,这样他们的长度才能是最长的。

例子:

那么现在我们再考虑X不等于Y的情况:

此处的解释:

当我们认为是我们子序列的子串的最后一个元素不相等,那么他的最长子序列一定来自两个地方,假设去掉X序列的最后一个元素,那么最长子序列一定产生于图中A+B+Yn,同理一样, B+A+Xn.

例子:

总结:

怎么求呢?C[m,n]是一个正整数的值,表示序列m和n之间的最大的长度。

当两个字符串有一个是0 ,那么LCS一定是0;

例子:

右下角的数据怎么计算呢?

经过上面的分析,我们知道两个序列有一个是0 的那么LCS都是0 ;所以第0行第0列都是0.

图中红圈内1怎么得来的呢?

红圈内的x是B,y是D,即x不等于y.那么我们就要看红圈上左边和上边 的数值了,选择一个大的数值写入。

那么以此类推,当x=y 的时候,我们直接选择红圈左上的值+1,写入即可。

两个例子来自点击打开链接

代码一是让你输入两个序列,然后输出最长公共子序列和长度。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int LCSLength(char* str1, char* str2, int **b)
{  int i,j,length1,length2,len;  length1 = strlen(str1);  length2 = strlen(str2);  //双指针的方法申请动态二维数组  int **c = new int*[length1+1]; //共有length1+1行  for(i = 0; i < length1+1; i++)  c[i] = new int[length2+1];//共有length2+1列  for(i = 0; i < length1+1; i++)  c[i][0]=0;        //第0列都初始化为0  for(j = 0; j < length2+1; j++)  c[0][j]=0;        //第0行都初始化为0  for(i = 1; i < length1+1; i++)  {  for(j = 1; j < length2+1; j++)  {  if(str1[i-1]==str2[j-1])//由于c[][]的0行0列没有使用,c[][]的第i行元素对应str1的第i-1个元素  {  c[i][j]=c[i-1][j-1]+1;  b[i][j]=0;          //输出公共子串时的搜索方向  }  else if(c[i-1][j]>c[i][j-1])  {  c[i][j]=c[i-1][j];  b[i][j]=1;  }  else  {  c[i][j]=c[i][j-1];  b[i][j]=-1;  }  }  }  /* for(i= 0; i < length1+1; i++) { for(j = 0; j < length2+1; j++) printf("%d ",c[i][j]); printf("\n"); } */  len=c[length1][length2];  for(i = 0; i < length1+1; i++)    //释放动态申请的二维数组  delete[] c[i];  delete[] c;  return len;
}
void PrintLCS(int **b, char *str1, int i, int j)
{  if(i==0 || j==0)  return ;  if(b[i][j]==0)  {  PrintLCS(b, str1, i-1, j-1);//从后面开始递归,所以要先递归到子串的前面,然后从前往后开始输出子串  printf("%c",str1[i-1]);//c[][]的第i行元素对应str1的第i-1个元素  }  else if(b[i][j]==1)  PrintLCS(b, str1, i-1, j);  else  PrintLCS(b, str1, i, j-1);
}  int main(void)
{  char str1[100],str2[100];  int i,length1,length2,len;  printf("请输入第一个字符串:");  gets(str1);  printf("请输入第二个字符串:");  gets(str2);  length1 = strlen(str1);  length2 = strlen(str2);  //双指针的方法申请动态二维数组  int **b = new int*[length1+1];  for(i= 0; i < length1+1; i++)  b[i] = new int[length2+1];  len=LCSLength(str1,str2,b);  printf("最长公共子序列的长度为:%d\n",len);  printf("最长公共子序列为:");  PrintLCS(b,str1,length1,length2);  printf("\n");  for(i = 0; i < length1+1; i++)//释放动态申请的二维数组  delete[] b[i];  delete[] b;  system("pause");  return 0;
}  

大白话讲解LCS(最长公共子序列)相关推荐

  1. 算法设计 - LCS 最长公共子序列最长公共子串 LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...

  2. LCS最长公共子序列和LIS最长上升子序列——例题剖析

    一.LCS最长公共子序列 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我) longest comment subsequence 模板题 longe ...

  3. LCS(最长公共子序列)及其O(n)空间优化,O(nlogn)时间复杂度优化

    LCS(最长公共子序列)及其O(n)空间优化,O(nlogn)时间复杂度优化 n^2 的版本 int LCS_n_2(vector<char> &a,vector<char& ...

  4. 动态规划求解LCS最长公共子序列问题c++

    文章目录 求最长公共子序列 最长公共子序列问题 刻画最长公共子序列的特征 递归公式 C++代码 求最长公共子序列长度 打印任意一组最长公共子序列 模板题 求最长公共子序列 最长公共子序列问题 (Lon ...

  5. LCS(最长公共子序列)

    题意描述 求两个字符串的最长公共子序列的长度 动态规划 用二维数组 C[i][j] 记录串x1x2⋯xi与y1y2⋯yj 的 LCS长度,则可得到状态转移方程: 代码实现: #include<i ...

  6. LCS/最长公共子序列/最长公共子串 实现 Python/Java

    参考 http://blog.csdn.net/u012102306/article/details/53184446 http://blog.csdn.net/hrn1216/article/det ...

  7. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  8. POJ 1458 Common Subsequence DP LCS 最长公共子序列

    最长公共子序列,照抄<算法设计与分析导论>P138-140 设输入的两个字符串分别为a1,a2,```,am(串a) b1,b2,````,bn(串b) 设d(i,j)为字符串a1,a2, ...

  9. LCS最长公共子序列

    例如 b c d d e和 a c e e d e的公共子串为c d e. 如果使用暴力,复杂度太高会直接超时.就需要使用动态规划 dp[i][j]表示a串第i个结尾,b串第j个结尾的最长公共子串的数 ...

最新文章

  1. Element 'dependency' cannot have character [children]
  2. 网易智慧企业亮相TOP 100 Summit,以创新和匠心探索行业前沿
  3. 工业机器人工具中心点标定的意义_如何理解工业机器人的工具中心点
  4. sql语句优化之not in
  5. Split Temporary Variable(分解临时变量)
  6. python hack_Python进阶:深入GIL(上篇)
  7. Python使用Tornado+Redis维护ADSL拨号服务器代理池
  8. MySQL 字符串转in/double类型——CAST/CONVERT函数的用法
  9. Spring入门-框架搭建
  10. 日志存储 elasticsearch vs clickhouse
  11. Windows批处理BAT脚本
  12. oracle rac 在完成安装错误。
  13. IDEA的常用快捷键(超详细)
  14. 在python中安装包出现Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
  15. 【Kafka】ZK、Kafka以及EFAK的安装、配置
  16. 海南大学 838信号与系统专业课的感悟
  17. Java应用系列之Pinyin4j简单使用教程
  18. java倒计时器_java – 使用计时器倒计时
  19. Git配置、版本控制与分支管理
  20. 国内免费(开源)CMS系统【大全】

热门文章

  1. 金x修改器连接服务器怎么办,金X存档修改器 天赋物品更新版 附控制台补丁
  2. 苹果Macbook经常死机怎么办?
  3. Python程序员面试中,被常问的七道题!(详细解题思路)
  4. PID控制器的传递函数推导
  5. Java替换Word模板中的文字、图片、表格、水印
  6. 服务器拒绝了你发送文件请求,服务器拒绝了您发送离线文件是怎么回事
  7. lamp部署配置及部署phpmyadmin
  8. 龙族幻想每个职业的圣核怎么加呢
  9. 2021年美赛E题目简述(中英文)
  10. Python之探索式数据分析