LCS算法:最长公共子序列定义:
一个序列A任意删除若干个字符得到新序列B,则A叫做B的子序列
两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列
例如:

X={A,B,C,B,D,A,B}
Y={B,D,C,A,B,A}
则它们的lcs分别是
{B,C,B,A}
{B,D,A,B}。
求出一个即可。
LCS的

LCS算法符号表示:

 字符串X,长度m,从1开始计数字符串Y,长度n,从1开始计数Xi=<x1,x2,...,xi>表示X序列的前i个字符(1<=i<=m)Yj=<y1,y2,...,yj>表示Y序列的前j个字符(1<=j<=n)LCS(X,Y)为字符串X和Y的最长公共子序列其中的一个解为Z=<z1,z2,....zk>注意:LCS(X,Y)其实为一个集合Z为一个解

用递归的思想去做的话,就从大到小从后往前推

            队列X=    A,B,C,B,D,A,B队列Y=      B,D,C,A,B,A栈A={}
共有两种情况:
1、最后一位相同:{①、X尾去一位,再重新和Y比较②、Y尾去一位,再重新和X比较}
2、最后一位相同:X、Y分别尾去一位(入栈,最后出栈就是答案),再重新X和Y比较

用动态规划的思想去做,从小到大从前往后推

规则:相同的取左上加1,不同取上和左中的最大值

推导结果如下:

最右下角的值就是答案;

代码实现:
/*** 计算最长公共子序列* @param strx* @param stry* @return 最长公共子序列的长度*/public static int lcs(String strx,String stry){int row=strx.length()+1;int col=stry.length()+1;char[] cx=strx.toCharArray();char[] cy=stry.toCharArray();int[][] arrays=new int[row][col];//使用动态规划的方式填入数据for (int i = 1; i < arrays.length; i++) {for (int j = 1; j < arrays[i].length; j++) {int max=0;if(cx[i-1]!=cy[j-1]){max=Math.max(arrays[i-1][j], arrays[i][j-1]);}else{max=arrays[i-1][j-1]+1;}arrays[i][j]=max;}}//打印for (int i = 0; i < arrays.length; i++) {for (int j = 0; j < arrays[i].length; j++) {System.out.print(arrays[i][j]+" ");}System.out.println();}printLCS(cx,cy,arrays);return arrays[row-1][col-1];}
程序运行结果:0   0   0   0   0   0   0
0   0   0   0   1   1   1
0   1   1   1   1   2   2
0   1   1   2   2   2   2
0   1   1   2   2   3   3
0   1   2   2   2   3   3
0   1   2   2   3   3   4
0   1   2   2   3   4   4

打印答案的话需要回溯处理:
从最后一位回溯:

1、如果i和j 对于的char 不相同,则选上、中最大那个方向走如果都一样就代表有多个答案,每个方向就是一个答案,方向:i-1和j   或者  i和j -12、如果i和j 对于的char 相同,则就把相应的char入栈,方向:i和j 都分别减一一直重复1、2操作到轮询结束,打印栈就是答案。例如:i=7,j=6  value[i][j]=4,4的上、左最大为4,那么尝试从上走(绿色)·····栈={A,B,C,B}打印结果:B,C,B,Ai=7,j=6  value[i][j]=4,4的上、左最大为4,那么尝试从左走(紫色)·····栈={B,A,D,B}打印结果:B,D,A,B

推导结果如下:

代码实现:
/*** 打印最长公共子序列* @param arrays*/public static void printLCS(char[] cx,char[] cy,int[][] arrays){Stack<String> stack =new Stack<>();int row=arrays.length-1;int col=arrays[0].length-1;while(row>0&&col>0){if(cx[row-1]!=cy[col-1]){if(arrays[row-1][col]>=arrays[row][col-1]){row-=1;}else if(arrays[row-1][col]<arrays[row][col-1]){col-=1;}}else{stack.push(cx[row-1]+"");row-=1;col-=1;}}while(!stack.isEmpty()){System.out.print(stack.pop()+"  ");}}程序运行结果:B   C   B   A   

LCS的应用:
相似度的比较:计算生物学DNA对比(亲子验证),百度云盘找非法数据(岛国片)
图形相似处理,媒体流的相似比较,百度知道,百度百科,WEB页面中找非法言论等

LCS算法:最长公共子序列相关推荐

  1. 实验二 动态规划算法 最长公共子序列问题

    基本题一:最长公共子序列问题 一.实验目的与要求 1.熟悉最长公共子序列问题的算法: 2.初步掌握动态规划算法: 二.实验题 若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,z ...

  2. NLP文本相似度 - LCS(最长公共子序列)java代码

    LCS是Longest Common Subsequence的缩写,即最长公共子序列.一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列. 比如,对于char x[ ...

  3. JAVA实现基于LCS(最长公共子序列)的文本比对

    文章目录 最长公共子序列 求解最长公共子序列 确定状态转移方程 如何求出最长的公共子序列 如何实现文本比对 比对效果图 参考文章: 最近因为项目需求需要实现一个文本比对的功能,自然的就想到了git的文 ...

  4. 动态规划算法——最长公共子序列求法

    给定序列X={ X1,X2,....Xn }.Y={ Y1,Y2,...Ym }找出它们的最大子序列Z={ Z1,Z2,...Zk }比如:X={ A,B ,C,B,D,A,B }.Y={ B,D,C ...

  5. 穷举法求最大公共子序列C语言,算法--最长公共子序列(LongestCommon Subsequence, LCS)...

    定义: 两个字符串共有的最长的子序列(可不连续),最长公共字符串(Longest CommonSubstring)是两个字符串共有的最长的连续字符串. 方法:穷举法,动态规划 动态规划法的简介: &l ...

  6. 动态规划经典算法--最长公共子序列 LCS

    转移方程 代码: //法一: #include <bits/stdc++.h> using namespace std; //---------------https://lunatic. ...

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

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

  8. 编辑距离:最长公共子序列-LCS问题

    一.基本概念 LCS是最长公共子序列(Longest common subsequence problem)的缩写.LCS问题是在一组序列(通常只有两个序列)中找到所有序列共有的最长子序列的问题.它与 ...

  9. 触类旁通,经典面试题最长公共子序列应该这么答

    作者 |  labuladong 来源 | labuladong(ID:labuladong) [导读]最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经 ...

  10. 【恋上数据结构】动态规划(找零钱、最大连续子序列和、最长上升子序列、最长公共子序列、最长公共子串、0-1背包)

    动态规划(Dynamic Programming) 练习1:找零钱 找零钱 - 暴力递归 找零钱 - 记忆化搜索 找零钱 - 递推 思考题:输出找零钱的具体方案(具体是用了哪些面值的硬币) 找零钱 - ...

最新文章

  1. 产权分割商铺,太坑人!
  2. python读取中文-python读取中文txt文本
  3. oracle文件大小的限制
  4. 干货分享:六个知名的Go语言web框架
  5. CapcityScheduler配置方法(还没弄完)
  6. Linux学习之第二课时--linux命令格式及命令概述
  7. AutoCompleteExtender智能扩展实例
  8. 创业者创业之前,应该思考如下这些问题
  9. vue 父组件使用keep-alive和infinite-scroll导致在子组件触发父组件的infinite-scroll方法...
  10. Android开发学习笔记:数据存取之File浅析
  11. 结合 TreeMap 源码分析红黑树在 java 中的实现
  12. oracle mysql odbc驱动程序_oracle odbc驱动下载
  13. ubuntu 下android设备找到fastboot驱动
  14. 分享个三国志2017挂机脚本 可玩性很高占用小
  15. UE4 VR官方教程学习总结-项目设置
  16. CDH环境HDFS权限问题
  17. php调用和风天气api,推荐一个免费7天天气预报API服务:和风天气
  18. Workbench二次开发技术分享
  19. 数据重塑_Google是否会重塑电话
  20. (数电实验报告)用Verilog–HDL语言设计一个8线3线优先编码器

热门文章

  1. AspectJ的Execution表达式
  2. 【Spring】AOP(二)自定义来实现AOP
  3. 词性、句法分析、依存关系的符号解释
  4. C语言中alarm的应用
  5. html video标签canplay,HTML oncanplay事件用法及代码示例
  6. java中的arrayList(动态数组)与静态数组
  7. 磁盘分区形式:主启动记录(MBR)和全局唯一标识分区表(GPT)
  8. “术业有专攻”和“功夫在行外”--笑来
  9. 文本输出API函数:TextOut,ExtTextOut,DrawText,DrawTextEx,PolyTextOut,TabbedTextOut
  10. LruCache缓存方法