最长公共子序,到底啥是最长公共子序列?子序列跟公共子串有啥区别?
最长公共子序列:是两个或多个系列的公共的最长的子序列,在子序列当中,下标呈严格的递增序列;
最长公共子串:是在最长公共子序列当中,下标呈相连的子序列当中最长的子串。
例如: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)是一个经典的计算机科学问题,涉及序列比较和算法设计。在本实验报告中,我们将深入探讨如何利用动态规划方法解决这一问题。 首先,LCS问题旨在找到两个给定序列...
### 最长公共子序列算法总结 #### 一、O(n^2)算法 在讨论最长公共子序列(Longest Common Subsequence,简称LCS)问题时,通常会提及两种主要的算法实现方式:一种时间复杂度为O(n^2),另一种则通过优化达到O...
在动态规划算法中,需要考虑两个子问题:(1) 找出 X m – 1 和 Y 的最长公共子序列,(2) 找出 X 和 Y n – 1 的最长公共子序列。然后,可以使用以下递推式来计算 c[i][j]:c[i][j] = c[i - 1][j - 1] + 1, x i = y j...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的字符串问题,广泛应用于文本比较、生物信息学等领域。本实验报告主要围绕LCS算法的实现及其实验过程进行深入探讨。 首先,我们要...
最长公共子序列(Longest Common Subsequence,简称LCS)问题属于计算机科学领域中的一个重要问题,尤其是在算法设计与分析方面。此问题的核心在于寻找两个序列的最长公共子序列。其中,“子序列”指的是在原序列中...
【最长公共子序列(动态规划)】是一种经典的算法问题,主要应用于序列比对、文本处理等领域。本实验报告详尽地介绍了如何运用动态规划解决这一问题。 动态规划是一种解决复杂问题的有效方法,它通过将大问题分解为...
### C++实现最长公共子序列算法详解 在深入解析给定代码之前,我们先来了解一下“最长公共子序列”(Longest Common Subsequence,简称LCS)的基本概念及其在计算机科学中的应用。LCS问题是一种典型的动态规划问题...
在这个实验报告中,我们通过动态规划法解决了最长公共子序列问题和0-1背包问题,并对算法的正确性进行了证明。实验结果表明,动态规划法可以有效地解决这两个问题。 实验总结 通过这次实验,我们深入理解了动态...
本次实验旨在使学生掌握如何运用动态规划策略来解决最长公共子序列(Longest Common Subsequence, LCS)问题,并通过编程实践加深对动态规划算法的理解。 #### 实验原理 **动态规划算法设计**是一种通过将复杂问题...
最长公共子序列问题LCS 最长公共子序列问题(Longest Common Subsequence,LCS)是计算机科学中一个经典的问题,它是指给定两个序列X和Y,找出它们的最长公共子序列。该问题具有重要的理论和实际意义,在很多领域都...
最长公共子序列问题是计算机科学中一个经典的算法问题,主要应用于生物信息学、自然语言处理等领域。给定两个字符串`X = x1x2...xm`和`Y = y1y2...yn`,它们的一个共同子序列是同时为两个序列的子序列的任意序列。...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要应用于比较和分析两个或多个序列的相似性。在这个问题中,目标是找到两个序列的最长子序列,这个子序列不需要在原序列中...
根据给定的文件信息,我们可以总结出以下关于“输出最长公共子序列”的C语言实现的知识点: ### 一、最长公共子序列问题介绍 最长公共子序列(Longest Common Subsequence,简称 LCS)是一个经典的计算机科学问题...
利用动态规划 实现排序 找到最长公共工子序列
采用位运算计算出最长公共子序列,高效便捷 采用位运算计算出最长公共子序列,高效便捷 采用位运算计算出最长公共子序列,高效便捷 采用位运算计算出最长公共子序列,高效便捷 采用位运算计算出最长公共子序列,高效...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计和分析。它的目标是找到两个给定序列(通常为字符串)的最长子序列,该子序列在原序列中不需连续,但必须...
1. 掌握动态规划法的设计思想并能熟练运用 2. 强化动手编程的能力 二. 实验内容 用动态规划法求两个序列的最大公共子序列 三. 算法思想 1. 分析可得如下动态规划函数: ① L[0][0]=L[i][0]=L...
动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...
C源程序——两个序列的最大公共子序列#include #include #define MAX 100 char x[MAX+1],y[MAX+1]; int b[MAX+1][MAX+1],c[MAX+1][MAX+1],m,n; static void Init_XY(void); static void LCS_Length(void); static...
动态规划是一种强大的算法思想,广泛应用于计算机科学,特别是在解决最优化问题时,如寻找最长公共子序列(Longest Common Subsequence, LCS)。本主题聚焦于使用动态规划方法求解最长公共子序列问题,并通过C++语言...