最长公共子序,到底啥是最长公共子序列?子序列跟公共子串有啥区别?
最长公共子序列:是两个或多个系列的公共的最长的子序列,在子序列当中,下标呈严格的递增序列;
最长公共子串:是在最长公共子序列当中,下标呈相连的子序列当中最长的子串。
例如:X={A,B,C,D,A,B},Y={B,C,B,D,B}.最长公共子序列Z={B,C,D,B},最长公共子串C={B,C}.
基本定理:
若两个序列X={x1,x2,…,xn},Y={y1,y2,…,ym}的最长公共子序列Z={z1,z2,…,zk};
- 若xn=ym,则zk=xn=ym,且Zk-1 是Xn-1与Ym-1的最长公共子序列;
- 若xn!=ym,zk!=xn,则Z 是Xn-1与Y 的最长公共子序列;
- 若xn!=ym,zk!=ym,则Z是X与Ym-1的最长公共子序列。
那么问题来了,在序列当中怎么求最长公共子序列?
最常用的两种方法:穷举法,动态规划法。
穷举法:求两个序列X={x1,x2,…,xn},Y={y1,y2,…,ym}的最长公共子序列。列出X的所有子序列,再用那个子序列去匹配Y的子序列,匹配成功则记录下该子序列的长度和该子序列,待全部的子序列匹配完毕就可以找到X,Y两序列的最长公共子序列。这样的时间复杂度有点儿大的惊人,O(2^n*2^m).
动态规划法:求两个序列X={x1,x2,…,xn},Y={y1,y2,…,ym}的最长公共子序列。
1、若Xn=Ym ,则先求出Xn-1与Ym-1的最长公共子序列,再加上Xn就是X,Y的最长公共子序列了;
2、若Xn!=Ym,则先求出X与Ym-1,Xn-1与Y的最长公共子序列,再去两者的最长子序列即可。
| 0 i,j=0
推导式:C[i][j]| C[i-1][j-1]+1 i,j>0,Xi=Yj
| Max{C[i][j-1],C[i-1][j]}
| i,j>0,Xi!=Yj
源码:
package com.usc.lilin.LCSProblem; /** * 算法课题探究 * 最长公共子序列 * @author gaosi * */ public class LCSProblem { public static void main(String[] args) { //保留空字符串是为了getLength()方法的完整性也可以不保留 //但是在getLength()方法里面必须额外的初始化c[][]第一个行第一列 String[] x = {"", "A", "B", "C", "B", "D", "A", "B"}; String[] y = {"", "B", "D", "C", "A", "B", "A"}; int[][] b = getLength(x, y); //以x数组为标准比较,数组x,y的最大下标为x.length-1, y.length-1; Display(b, x, x.length-1, y.length-1); } /** * 获取每个数据的比较情况 * @param x * @param y * @return 返回一个记录决定搜索的方向的数组 */ public static int[][] getLength(String[] x, String[] y) { //数组b用来存放0,1,-1标记 int[][] b = new int[x.length][y.length]; int[][] c = new int[x.length][y.length]; for(int i=1; i<x.length; i++) { for(int j=1; j<y.length; j++) { //对应第一个性质(如果某位置字符数组的内容相同,将其对应队列位置赋值为1) if( x[i] == y[j]) { c[i][j] = c[i-1][j-1] + 1; b[i][j] = 1; } //对应第二或者第三个性质(如果其队列c左边数大于上边的,将其对应位置赋值为0) else if(c[i-1][j] >= c[i][j-1]) { //对应图中箭头上移 c[i][j] = c[i-1][j]; b[i][j] = 0; } //对应第二或者第三个性质(如果其队列c左边数小于上边的,将其对应位置赋值为-1) else { //对应图中箭头左移 c[i][j] = c[i][j-1]; b[i][j] = -1; } } } return b; } /** * 回溯的基本实现,采取递归的方式 * @param b 标志每个元素的比较情况的二维数组 * @param x 序列 * @param i 递归的大小 * @param j 递归的大小 */ public static void Display(int[][] b, String[] x, int i, int j) { if(i == 0 || j == 0) return; if(b[i][j] == 1) { Display(b, x, i-1, j-1); System.out.print(x[i] + " "); } else if(b[i][j] == 0) { Display(b, x, i-1, j); } else if(b[i][j] == -1) { Display(b, x, i, j-1); } } }
相关推荐
这是一个有关算法的压缩包,里面包含二分算法、合并排序、最长公共子序列、最优装载、活动安排算法
最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和动态规划算法。在本场景中,我们使用C#编程语言来解决这个问题。C#是一种多范式编程语言,广泛应用于开发...
【最长公共子序列(动态规划)】是一种经典的算法问题,主要应用于序列比对、文本处理等领域。本实验报告详尽地介绍了如何运用动态规划解决这一问题。 动态规划是一种解决复杂问题的有效方法,它通过将大问题分解为...
实现了求最长公共子序列的算法,内容简单易懂,代码也很短
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一个重要的算法问题,它主要应用于字符串比较、文本编辑、生物信息学等领域。在文本编辑器中,LCS用于比较两份文档的差异,帮助进行合并或冲突...
本次实验旨在使学生掌握如何运用动态规划策略来解决最长公共子序列(Longest Common Subsequence, LCS)问题,并通过编程实践加深对动态规划算法的理解。 #### 实验原理 **动态规划算法设计**是一种通过将复杂问题...
总的来说,动态规划和KR算法都是求解最长公共子序列的有效方法,它们各有特点,适用于不同的编程环境和需求。而KMP算法则专注于高效的字符串匹配,虽然与LCS问题不是直接相关,但在字符串处理领域中同样重要。
【最长公共子序列算法】 最长公共子序列(Longest Common Subsequence, LCS)问题是一个经典的计算机科学问题,属于算法分析的范畴。该算法主要用于找出两个序列间的最长子序列,这个子序列并不需要连续,但必须...
1. 掌握动态规划法的设计思想并能熟练运用 2. 强化动手编程的能力 二. 实验内容 用动态规划法求两个序列的最大公共子序列 三. 算法思想 1. 分析可得如下动态规划函数: ① L[0][0]=L[i][0]=L...
动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...
“动态规划法求解最长公共子序列问题&0-1背包问题” 动态规划是一种非常重要的算法设计方法,应用于解决很多复杂的问题。动态规划法可以将问题分解成若干个小问题,然后通过解决每个小问题来解决整个问题。在实验2...
动态规划的一个计算两个序列的最长公共子序列的方法如下: 以两个序列 X、Y 为例子: 设有二维数组 f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有: f[1][1] = same(1,1); f[i,j] = max{f[i-1...
最长公共子序列(Longest Common Subsequence,LCS)问题是计算机科学中一个经典的字符串处理问题,主要涉及到动态规划算法的应用。在这个问题中,目标是找到两个序列的最长子序列,这个子序列不必连续,但必须在原...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计与分析,特别是在动态规划领域的应用。在这个问题中,我们需要找到两个或多个字符串之间的最长子序列,这...
### 最长公共子序列(Longest Common Subsequence, LCS) #### 定义与概念 最长公共子序列问题(LCS)是计算机科学中的一个经典问题,它涉及到在两个或多个序列中寻找最长的相同子序列。这里所说的“子序列”并不...
哈工大算法实验二,最长公共子序列问题,动态规划解决LCS 1.实现基于优化子结构的递归求解算法 2.实现基于动态规划的求解算法 3.实现三个字符串最长公共子序列的动态规划算法 4.有界面源代码和实验报告!均为自己所...
最长公共子序列(Longest Common Subsequence, LCS)是计算机科学中一种经典的字符串问题,它在比较两个或多个序列时寻找它们之间的最长相同部分,但这个相同部分不需要连续。这个问题在许多领域都有应用,比如生物...
最长公共子序列(Longest Common Subsequence,LCS)算法是一种经典的计算机科学问题,主要应用于比较和分析两个或多个序列的相似性。在文本编辑、生物信息学、数据挖掘等领域有着广泛的应用。LCS的基本思想是寻找两...
最长公共子序列问题 for ( i = 0; i ; i++) { c[i] = new int[n+1]; } for(i=0;i;i++) {c[i][0]=0;b[i][0]=0;} for(i=0;i;i++) {c[0][i]=0;b[0][i]=0;} for(i=1;i;i++) for(j=1;j;j++) if(s1[i-1]==s2[j...
【问题描述】字符序列的子序列是指从给定字符序列中随意地(不一定要联系)去掉若干个字符...给定两个序列A和B,称序列Z是A和B的公共子序列,是指Z同是A和B的子序列,该问题是求两序列A和B的最长公共子序列(LCS)