`
TiFa.L.Hart
  • 浏览: 16716 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

动态规划--最长公共子序列

阅读更多
     X和Y,当另一序列Z既是X的子序列又是Y的子序列时,若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
    同理,若序列Z既是X的子序列同时也是Y的子序列,则称Z为X和Y的公共子序列。其中最长的子序列称为最长公共子序列。
   在求最长公共子序列中,我们可以看出如下规律:
   设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则
   (1)若xm=yn,则zk=xm=yn,且zk-1是xm-1和yn-1的最长公共子序列。

   (2)若xm≠yn且zk≠xm,则Z是xm-1和Y的最长公共子序列。(即:Z是X序列中前m个元素所组成的序列与Y序列的最长公共子序列)

   (3)若xm≠yn且zk≠yn,则Z是X和yn-1的最长公共子序列。(即:Z是Y序列中前n个元素所组成的序列与X序列的最长公共子序列)

  由上面三个条件可得如下公式:
C[][]用来记录最长公共子序列的长度,则:
c[i][j] = <1> 0;                                     (当i、j = 0时);
            <2> c[i-1][j-1] + 1;                   (当i、j > 0 且 Xi = Yj时)(即第i个X序列元素与第j个Y元素相等)
            <3> max(c[i][j-1] , c[i-1][j])       (当i、j > 0 且 Xi != Yj时)(当Xi与Yj不等时,取两个式子的最大值,若两者相等则默认取第一个)


/**
	 * 求出最大子序列的长度
	 * @param x 数组1
	 * @param y 数组2
	 * @param b 用于存放两个数组内容比较的情况
	 * @return  返回最大子序列的长度
	 */
	public static int lcsLength(String[] x, String[] y, int[][] b) {
		int m = x.length - 1;
		int n = y.length - 1;
		
		int[][] c = new int[m + 1][n + 1];
		
		for (int i = 1; i <= m; i++){
			c[i][0] = 0;
		}
		for (int i = 1; i <= n; i++)
			c[0][i] = 0;
		

		for (int i = 1; i <= m; i++) {
			for (int j = 1; j <= n; j++) {
				if (x[i].equals(y[j])) {
					c[i][j] = c[i - 1][j - 1] + 1;
					b[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[m][n];
	}

	/**
	 * 构造最长公共子序列
	 * @param i 第一个数组的长度
	 * @param j 第二个数组的长度
	 * @param x 两个数组中的一个
	 * @param b 记录了公共子序列情况的数组,该数组在lcs
	 */
	public static void lcs(int i, int j, String[] x, int[][] b) {
		if (i == 0 || j == 0)
			return;
		if (b[i][j] == 1) {
			lcs(i - 1, j - 1, x, b);
			System.out.print(x[i]+"	 ");
		} else if (b[i][j] == 2)
			lcs(i - 1, j, x, b);
		else
			lcs(i, j - 1, x, b);
	}
	
	/**
	 * 初始化数组的方法
	 * @param str 要转化为数组的字符串
	 * @return 返回str转化成的数组
	 */
	private String[] init(String str){
		String temp = str;
		String[] s = temp.split("");
		return s;
	}


本来想将实现匹配公共子序列的矩阵的步骤的图贴上来的,但是不知道怎么用这个东西贴,真头疼....

   main方法测试:
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String s1 = "ABCBDAB";
		String s2 = "BDCABA";
		CountMaxSerial cms = new CountMaxSerial();
		String[] x = cms.init(s1);
		String[] y = cms.init(s2);
		int[][] b = new int[x.length][y.length];
		
		System.out.println("最大子序列的长度为:"+lcsLength(x, y, b));
		System.out.println("最大子序列为:");
		lcs(x.length-1, y.length-1, x, b);
		
	}
  
分享到:
评论

相关推荐

    算法设计与分析实验报告-动态规划寻找最长公共子序列.doc

    实验报告的主题是“算法设计与分析”,关注的是使用动态规划解决最长公共子序列(Longest Common Subsequence, LCS)的问题。动态规划是一种有效的方法,它适用于具有最优子结构和子问题重叠性质的问题。在本实验中...

    C#实现-动态规划-最长公共子序列-DPLCS

    本主题聚焦于使用C#语言实现动态规划来求解“最长公共子序列”(Longest Common Subsequence,简称LCS)问题。最长公共子序列是指两个或多个字符串中的一个非空子序列,它在原序列中保持原有的相对顺序,但不一定...

    动态规划--求最长公共子序列问题

    只供参考,如有觉得不当的地方请指正! 当然这个问题还有很多种方法,但是我是理由动态分配内存来解决这个问题的,后面有delete来释放分配的内存单元。

    动态规划中的最长公共子序列PPT课件.pptx

    动态规划中的最长公共子序列 动态规划中的最长公共子序列是指给定两个序列 X 和 Y,找到他们的最长公共子序列的长度和该子序列本身。该问题是计算机科学中的一类典型问题,广泛应用于数据压缩、数据挖掘、生物信息...

    最长公共子序列(动态规划)报告.doc

    【最长公共子序列(动态规划)】是一种经典的算法问题,主要应用于序列比对、文本处理等领域。本实验报告详尽地介绍了如何运用动态规划解决这一问题。 动态规划是一种解决复杂问题的有效方法,它通过将大问题分解为...

    最长公共子序列实验报告

    总之,最长公共子序列问题可以通过动态规划有效地解决,通过构建并填充c和b数组,不仅可以得到LCS的长度,还可以重建LCS本身。这种算法的时间复杂度为O(m * n),显著优于指数级的穷举搜索方法。

    实验2. 动态规划法求解最长公共子序列问题与0-1背包问题.doc

    动态规划法求解最长公共子序列问题与0-1背包问题 本实验报告旨在通过动态规划法解决最长公共子序列问题和0-1背包问题,以深入理解动态规划方法的思想、求解策略及步骤。 实验目的 * 理解动态规划方法的核心思想和...

    奥赛动态规划法最长公共子序列

    接下来的LCSLength函数实现这个动态规划过程,而LCS函数则用于根据存储的c数组回溯并打印出最长公共子序列。在算法的改进部分,我们注意到数组b实际上是可以省略的,因为c[i][j]的值仅取决于c[i-1][j-1]、c[i-1][j]...

    动态规划实现最长公共子序列

    利用动态规划 实现排序 找到最长公共工子序列

    C#-回溯-最长公共子序列-DCLCS

    总之,"C#-回溯-最长公共子序列-DCLCS"是一个关于使用C#编程语言和回溯策略解决最长公共子序列问题的示例。回溯法通过试探性地构建解决方案并撤销无效选择来找到LCS,虽然不如动态规划高效,但在某些情况下仍然是一...

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

    动态规划算法求最长公共子序列 动态规划算法是一种常用的算法思想,它通过将复杂的问题分解成多个小问题,并将这些小问题的解组合起来,来解决复杂的问题。在这里,我们使用动态规划算法来求解最长公共子序列问题。...

    实验5--最长公共子序列 JAVA

    由此函数,把序列X={x1,x2….xm}和Y={y1,y2…ym}的最长公共子序列的搜索分为M个阶段,第1阶段,按照式1计算X1和Yj的最长公共子序列长度L[1][j](1),第2阶段,按照2式计算X2和Yj的最长公共子序列长度L[2][j](1),...

    实验2. 动态规划法求解最长公共子序列问题&0-1背包问题.doc

    “动态规划法求解最长公共子序列问题&0-1背包问题” 动态规划是一种非常重要的算法设计方法,应用于解决很多复杂的问题。动态规划法可以将问题分解成若干个小问题,然后通过解决每个小问题来解决整个问题。在实验2...

    最长公共子序列----算法分析之动态规划

    动态规划解决最长公共子序列问题,即寻找两个序列中公共的序列中的最长的那个,结果不唯一,只能输出一个最长公共子序列,并不能生成所有的; 可视化多文档,手动输入两个子序列,显示动态规划算法的解决表格,箭头...

    最长公共子序列动态规划算法

    ### 最长公共子序列动态规划算法 在计算机科学领域中,**最长公共子序列问题**(Longest Common Subsequence Problem, LCS)是一个经典的算法问题,它主要应用于文本比较、生物信息学中的DNA序列比对等领域。该问题...

    动态规划法解最长公共子序列

    1. 要求按动态规划法原理求解问题; 2. 两个序列数据通过键盘输入; 3. 要求显示结果。

    最长公共子序列--动态规划法实验

    最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种常见的问题,尤其在算法设计和分析中占有重要地位。这个问题涉及到序列比对,例如在文本编辑、生物信息学以及软件工程中都有应用。动态规划是...

    第四章 基本的算法策略-3-动态规划-最长公共子序列.pptx

    这部分内容主要涉及了算法设计中的一个重要概念——动态规划,并特别聚焦于如何利用动态规划解决最长公共子序列(LCS,Longest Common Subsequence)问题。下面我们将从以下几个方面进行详细阐述: ### 一、子序列...

    动态规划方法求解最长公共子序列代码

    动态规划是一种强大的算法思想,广泛应用于计算机科学,特别是在解决最优化问题时,如寻找最长公共子序列(Longest Common Subsequence, LCS)。本主题聚焦于使用动态规划方法求解最长公共子序列问题,并通过C++语言...

    动态规划——最长公共子序列和最长公共子串之Python实现

    用Python实现动态规划中最长公共子序列和最长公共子串问题!

Global site tag (gtag.js) - Google Analytics