《算法导论》读书笔记之动态规划—最长公共子序列 & 最长公共子串(LCS)
From:http://my.oschina.net/leejun2005/blog/117167
1、先科普下最长公共子序列 & 最长公共子串的区别:
找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。
2、最长公共子串
其实这是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")
b a b
c 0 0 0
a 0 1 0
b 1 0 1
a 0 1 0
我们看矩阵的斜对角线最长的那个就能找出最长公共子串。
不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1。
b a b
c 0 0 0
a 0 1 0
b 1 0 2
a 0 2 0
这样矩阵中的最大元素就是 最长公共子串的长度。
在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵。
2.1 代码如下:
public class LCString2 { public static void getLCString(char[] str1, char[] str2) {
int i, j;
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]; // 记录对角线上的相等值的个数 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;
} else {
c[j] = 0;
} if (c[j] > max[0]) { // 如果是大于那暂时只有一个是最长的,而且要把后面的清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 (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("123456abcd567");
String str2 = new String("234dddabc45678");
// String str1 = new String("aab12345678cde");
// String str2 = new String("ab1234yb1234567");
getLCString(str1.toCharArray(), str2.toCharArray());
}
}
ref:
LCS的java算法---考虑可能有多个相同的最长公共子串
http://blog.csdn.net/rabbitbug/article/details/1740557
最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
http://www.cnblogs.com/zhangchaoyang/articles/2012070.html
2.2 其实 awk 写起来也很容易:
echo "123456abcd567
234dddabc45678"|awk -vFS="" 'NR==1{str=$0}NR==2{N=NF;for(n=0;n++<N;){s="";for(t=n;t<=N;t++){s=s""$t;if(index(str,s)){a[n]=t-n;b[n]=s;if(m<=a[n])m=a[n]}else{t=N}}}}END{for(n=0;n++<N;)if(a[n]==m)print b[n]}'
ref:http://bbs.chinaunix.net/thread-4055834-2-1.html
3、最长公共子序列
import java.util.Random; public class LCS { public static void main(String[] args) { // 随机生成字符串
// String x = GetRandomStrings(substringLength1);
// String y = GetRandomStrings(substringLength2);
String x = "a1b2c3";
String y = "1a1wbz2c123a1b2c123";
// 设置字符串长度
int substringLength1 = x.length();
int substringLength2 = y.length(); // 具体大小可自行设置 // 构造二维数组记录子问题x[i]和y[i]的LCS的长度
int[][] opt = new int[substringLength1 + 1][substringLength2 + 1]; // 从后向前,动态规划计算所有子问题。也可从前到后。
for (int i = substringLength1 - 1; i >= 0; i--) {
for (int j = substringLength2 - 1; j >= 0; j--) {
if (x.charAt(i) == y.charAt(j))
opt[i][j] = opt[i + 1][j + 1] + 1;// 状态转移方程
else
opt[i][j] = Math.max(opt[i + 1][j], opt[i][j + 1]);// 状态转移方程
}
}
System.out.println("substring1:" + x);
System.out.println("substring2:" + y);
System.out.print("LCS:"); int i = 0, j = 0;
while (i < substringLength1 && j < substringLength2) {
if (x.charAt(i) == y.charAt(j)) {
System.out.print(x.charAt(i));
i++;
j++;
} else if (opt[i + 1][j] >= opt[i][j + 1])
i++;
else
j++;
}
} // 取得定长随机字符串
public static String GetRandomStrings(int length) {
StringBuffer buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
StringBuffer sb = new StringBuffer();
Random r = new Random();
int range = buffer.length();
for (int i = 0; i < length; i++) {
sb.append(buffer.charAt(r.nextInt(range)));
}
return sb.toString();
}
}
REF:
字符串最大公共子序列以及最大公共子串问题
http://gongqi.iteye.com/blog/1517447
动态规划算法解最长公共子序列LCS问题
http://blog.csdn.net/v_JULY_v/article/details/6110269
《算法导论》读书笔记之动态规划—最长公共子序列 & 最长公共子串(LCS)的更多相关文章
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- 《算法导论》— Chapter 15 动态规划
序 算法导论一书的第四部分-高级设计和分析技术从本章开始讨论,主要分析高效算法的三种重要技术:动态规划.贪心算法以及平摊分析三种. 首先,本章讨论动态规划,它是通过组合子问题的解而解决整个问题的,通常 ...
- 数据结构与算法JavaScript 读书笔记
由于自己在对数组操作这块比较薄弱,然后经高人指点,需要好好的攻读一下这本书籍,原本想这个书名就比较高深,这下不好玩了.不过看着看着突然觉得讲的东西都比较基础.不过很多东西,平时还是没有注意到,故写出读 ...
- 动态规划——最长公共子序列&&最长公共子串
最长公共子序列(LCS)是一类典型的动归问题. 问题 给定两个序列(整数序列或者字符串)A和B,序列的子序列定义为从序列中按照索引单调增加的顺序取出若干个元素得到的新的序列,比如从序列A中取出 A ...
- 二维动态规划&&二分查找的动态规划&&最长递增子序列&&最长连续递增子序列
题目描述与背景介绍 背景题目: [674. 最长连续递增序列]https://leetcode-cn.com/problems/longest-continuous-increasing-subseq ...
- 简单动态规划——最长公共子序列&&最长回文子序列&&最长上升||下降子序列
最长公共子序列,顾名思义当然是求两个字符串的最长公共子序列啦,当然,这只是一道非常菜的动规,所以直接附上代码: #include<iostream> #include<cstdio& ...
- 动态规划 ---- 最长公共子序列(Longest Common Subsequence, LCS)
分析: 完整代码: // 最长公共子序列 #include <stdio.h> #include <algorithm> using namespace std; ; char ...
- C语言 · 最长公共子序列 · 最长字符序列
算法提高篇有两个此类题目: 算法提高 最长字符序列 时间限制:1.0s 内存限制:256.0MB 最长字符序列 问题描述 设x(i), y(i), z(i)表示单个字符,则X={x( ...
随机推荐
- nrf51 SDK自带例程的解读
简单的pwm电机控制示例 simple_pwm_motor_control_example 其实就是pwm控制led的亮度 1.首先设置gpiote 设置初始为高电平2.接着设置ppi 定时器time ...
- SumoLogic
SumoLogic>>>Loggly. https://diyunpeng.loggly.com/setup MonitorWare http://www.monitorware.c ...
- WINDOWS操作系统中可以允许最大的线程数(线程栈预留1M空间)(56篇Windows博客值得一看)
WINDOWS操作系统中可以允许最大的线程数 默认情况下,一个线程的栈要预留1M的内存空间 而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程 但是内存当然不可能完全拿来 ...
- Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释
@jsonignore的作用作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响. http://www.cnblogs.com/toSeeMyDream/p/443 ...
- 在OSX狮子(Lion)上安装MYSQL(Install MySQL on Mac OSX)
这篇文章简述了在Mac OSX狮子(Lion)上安装MySQL Community Server最新版本v10.6.7的过程. MySQL是最流行的开源数据库管理系统.首先,从MySQL的下载页面上下 ...
- hdoj 1824 Let's go home(2-SAT)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1824 思路分析:该问题为2-SAT问题:需要注意逻辑推理的等价性: (1)题目第一个条件:每一个队或者 ...
- Struts2 学习笔记19 类型转换 Part1
现在来说一说类型转换,提到类型转换其实我们之前早已经用过了,在url传递参数的时候,我们传递过来的参数其实都是String类型的,在显示的时候都自动转换了,像这种简单的转换很好理解,我们要说的是,转换 ...
- CSS3媒体查询(Media Queries)
媒体类型: all 所有设备 screen 电脑显示器 handheld 便携设备 tv 电视类型设备 print 打印用纸打印预览视图 关键字 and not(排除某种设备) only(限定某种设备 ...
- BFG
"/"应用程序中的服务器错误. 配置错误 说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误消息: 提供程序集合中不 ...
- PHP面试题汇总参考
PHP面试题汇总 这是一份比较全面的PHP面试题.对准备去新公司应聘PHP职位的开发者应该有帮助.或者说,对招聘PHP开发人员的企业也有些帮助,不过就不要原样打印出来考了,稍微改一改. 简述题(50分 ...