经典算法-最长公共子序列(LCS)与最长公共子串(DP)
- public static int lcs(String str1, String str2) {
- int len1 = str1.length();
- int len2 = str2.length();
- int c[][] = new int[len1+1][len2+1];
- for (int i = 0; i <= len1; i++) {
- for( int j = 0; j <= len2; j++) {
- if(i == 0 || j == 0) {
- c[i][j] = 0;
- } else if (str1.charAt(i-1) == str2.charAt(j-1)) {
- c[i][j] = c[i-1][j-1] + 1;
- } else {
- c[i][j] = max(c[i - 1][j], c[i][j - 1]);
- }
- }
- }
- return c[len1][len2];
- }
- 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);
- Display(b, x, x.length-1, y.length-1);
- }
- /**
- * @param x
- * @param y
- * @return 返回一个记录决定搜索的方向的数组
- */
- public static int[][] getLength(String[] x, String[] y)
- {
- 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++)
- {
- //对应第一个性质
- if( x[i] == 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] = 0;
- }
- //对应第二或者第三个性质
- else
- {
- c[i][j] = c[i][j-1];
- b[i][j] = -1;
- }
- }
- }
- return b;
- }
- //回溯的基本实现,采取递归的方式
- 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);
- }
- }
- }
- public static int lcs(String str1, String str2) {
- int len1 = str1.length();
- int len2 = str2.length();
- int result = 0; //记录最长公共子串长度
- int c[][] = new int[len1+1][len2+1];
- for (int i = 0; i <= len1; i++) {
- for( int j = 0; j <= len2; j++) {
- if(i == 0 || j == 0) {
- c[i][j] = 0;
- } else if (str1.charAt(i-1) == str2.charAt(j-1)) {
- c[i][j] = c[i-1][j-1] + 1;
- result = max(c[i][j], result);
- } else {
- c[i][j] = 0;
- }
- }
- }
- return result;
- }
- public class stringCompare {
- //在动态规划矩阵生成方式当中,每生成一行,前面的那一行就已经没有用了,因此这里只需使用一维数组,而不是常用的二位数组
- public static void getLCString(char[] str1, char[] str2) {
- int len1, len2;
- len1 = str1.length;
- len2 = str2.length;
- int maxLen = len1 > len2 ? len1 : len2;
- int[] max = new int[maxLen];// 保存最长子串长度的数组
- int[] maxIndex = new int[maxLen];// 保存最长子串长度最大索引的数组
- int[] c = new int[maxLen];
- int i, j;
- for (i = 0; i < len2; i++) {
- for (j = len1 - 1; j >= 0; j--) {
- if (str2[i] == str1[j]) {
- if ((i == 0) || (j == 0))
- c[j] = 1;
- else
- c[j] = c[j - 1] + 1;//此时C[j-1]还是上次循环中的值,因为还没被重新赋值
- } else {
- c[j] = 0;
- }
- // 如果是大于那暂时只有一个是最长的,而且要把后面的清0;
- if (c[j] > max[0]) {
- max[0] = c[j];
- maxIndex[0] = j;
- for (int k = 1; k < maxLen; k++) {
- max[k] = 0;
- maxIndex[k] = 0;
- }
- }
- // 有多个是相同长度的子串
- else if (c[j] == max[0]) {
- for (int k = 1; k < maxLen; k++) {
- if (max[k] == 0) {
- max[k] = c[j];
- maxIndex[k] = j;
- break; // 在后面加一个就要退出循环了
- }
- }
- }
- }
- for (int temp : c) {
- System.out.print(temp);
- }
- System.out.println();
- }
- //打印最长子字符串
- for (j = 0; j < maxLen; j++) {
- if (max[j] > 0) {
- System.out.println("第" + (j + 1) + "个公共子串:");
- for (i = maxIndex[j] - max[j] + 1; i <= maxIndex[j]; i++)
- System.out.print(str1[i]);
- System.out.println(" ");
- }
- }
- }
- public static void main(String[] args) {
- String str1 = new String("binghaven");
- String str2 = new String("jingseven");
- getLCString(str1.toCharArray(), str2.toCharArray());
- }
- }
- /*
000000000
010000000
002000001
000300000
000000000
000000010
000000100
000000020
001000003
第1个公共子串:
ing
第2个公共子串:
ven
*/
经典算法-最长公共子序列(LCS)与最长公共子串(DP)的更多相关文章
- 每日一题-——最长公共子序列(LCS)与最长公共子串
最长公共子序列(LCS) 思路: 代码: def LCS(string1,string2): len1 = len(string1) len2 = len(string2) res = [[0 for ...
- 最长连续公共子序列(LCS)与最长递增公共子序列(LIS)
最长公共子序列(不连续) 实际问题中也有比较多的应用,比如,论文查重这种,就是很实际的一个使用方面. 这个应该是最常见的一种了,不再赘述,直接按照转移方程来进行: 按最普通的方式就是,直接构造二维矩阵 ...
- 51nod 1006 最长公共子序列Lcs(经典动态规划)
传送门 Description 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是 ...
- 编程算法 - 最长公共子序列(LCS) 代码(C)
最长公共子序列(LCS) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 给定两个字符串s,t, 求出这两个字符串最长的公共子序列的长度. 字符 ...
- 动态规划之最长公共子序列LCS(Longest Common Subsequence)
一.问题描述 由于最长公共子序列LCS是一个比较经典的问题,主要是采用动态规划(DP)算法去实现,理论方面的讲述也非常详尽,本文重点是程序的实现部分,所以理论方面的解释主要看这篇博客:http://b ...
- C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解
版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C++版 - L ...
- 1006 最长公共子序列Lcs
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...
- POJ 1458 Common Subsequence(最长公共子序列LCS)
POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...
- 51Nod 1006:最长公共子序列Lcs(打印LCS)
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
- 51nod 1006 最长公共子序列Lcs 【LCS/打印path】
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
随机推荐
- jquery ajax的知识点
jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...
- java修饰符——transient
一.背景 上星期去CRM上开发一个功能,该系统里面有自动分页,需要在实体类里加入一个分页变量 // 分页 private PageInfo pageInfo = new PageInfo(); 这个本 ...
- codeforces——contest 864 problemE
Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable it ...
- 【BZOJ】4430: [Nwerc2015]Guessing Camels赌骆驼
[题意]给定三个长度为n的排列,求在三个排列中顺序相同的数对个数. [算法]逆序对 [题解]很容易联想到NOIP火柴排队,涉及顺序问题显然和逆序对息息相关. 一个数对如果在三个排列中顺序不同,一定是1 ...
- ios的app,有新版本时必须先更新。
现在没时间整理,先把代码贴出来,以后再做详细的思路整理. 1 在AppController.mm的didFinishLaunchingWithOptions方法里面获取本地应用版本信息,保存起来. / ...
- nyoj 15 括号匹配(二) (经典dp)
题目链接 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些 ...
- Kill windows和linux 进程
Windows
- ubuntu中使用virtualbox遇到Kernel driver not installed (rc=-1908)错误
百度之后得到解决,再此做个笔记 错误提示 Kernel driver not installed (rc=-1908) The VirtualBox Linux kernel driver (vbox ...
- selenium===requestium模块介绍
有时,你可能会在网上实现一些自动化操作.比如抓取网站,进行应用测试,或在网上填表,但又不想使用API,这时自动化就变得很必要.Python提供了非常优秀的Requests库可以辅助进行这些操作.可惜, ...
- DevExpress.XtraTreeList 小结
搞了半天才绑定好,没有弄清楚父子之间的关系 <dx:ASPxTreeList ID="ASPxTreeList1" runat="server" Auto ...