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;elsec[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

2.3 perl的。。。真心没看懂。。。

#!/usr/bin/perl
use strict;
use warnings;my $str1 ="123456abcd567";
my $str2 = "234dddabc45678";
my $str = $str1 . "\n" . $str2;my (@substr,@result);
$str =~ /(.+)(?=.*\n.*\1)(*PRUNE)(?{push @substr,$1})(*F)/;
@substr = sort { length($b) <=> length($a) } @substr;
@result = grep { length == length $substr[0] } @substr;
print "@result\n";

ref:  http://bbs.chinaunix.net/thread-1333575-7-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;// 状态转移方程elseopt[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++;elsej++;}}// 取得定长随机字符串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

本文转自https://my.oschina.net/leejun2005/blog/117167,所有权力归原作者所有。

动态规划算法之:最长公共子序列 最长公共子串(LCS)相关推荐

  1. 最长公共子序列算法 java_转【算法之动态规划(三)】动态规划算法之:最长公共子序列 最长公共子串(LCS)字符串相似度算法...

    1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题 ...

  2. 算法设计 - LCS 最长公共子序列最长公共子串 LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解: 1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度: 2. 与之类似但不 ...

  3. 数据结构 - 字符串 - 最长公共子序列 + 最长公共子字符串 - 动态规划

    最长公共子序列 /*** 最长公共子序列* 参考链接:http://blog.csdn.net/biangren/article/details/8038605* Created by 18710 o ...

  4. 最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和...

    最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和 文章作者:Yx.Ac   文章来源:勇幸|Thinking (http://www.ahathi ...

  5. 最短公共子序列_最短公共超序列

    最短公共子序列 Problem statement: 问题陈述: Given two strings, you have to find the shortest common super seque ...

  6. 动态规划算法下的序列问题:最长公共子序列问题和最大子段和问题

    本篇主要介绍最长公共子序列问题和最大子段和问题 1.最长公共子序列问题 什么是最长公共子序列 给定一个序列X=<x1,x2,x3,x4-,xm>,另一个序列Z=<z1,z2,z3,z ...

  7. 动态规划之最长递增子序列 最长不重复子串 最长公共子序列

    [前言]动态规划:与分治法相似,即通过组合子问题来求解原问题,不同的是分治法是将问题划分为互不相交的子问题,递归求解子问题,再将他们组合起来求出原问题的解. 动态规划则应用于子问题重叠的情况,通常用来 ...

  8. 动态规划-最长公共子序列-最长递增子序列-最大递增子序列和-miking time

    1. 最长公共子序列 假设 X 和 Y 的序列如下: X[1...m] = {A, B, C, B, D, A, B} Y[1...n] = {B, D, C, A, B, A} 可以看出,X 和 Y ...

  9. java实现最长连续子序列_最长公共子序列/最长公共子串 Python/Java实现

    关注我的微信公众号:后端技术漫谈 不定期推送关于后端开发.爬虫.算法题.数据结构方面的原创技术文章,以及生活中的逸闻趣事. 我目前是一名后端开发工程师.主要关注后端开发,数据安全,网络爬虫,物联网,边 ...

最新文章

  1. CVPR2021直播|点云补全的方法梳理及最新进展分享
  2. 仓库管理员怎样做台账_工作日志之仓库管理员与会计之间的对接工作
  3. Vmware vSphere 5.0安装和配置
  4. 这个安全平台结合Spring Security逆天了,我准备研究一下
  5. 关于JAVA_HOME, CLASSPATH和PATH的设置
  6. 2021年中国医药营销数字化研究报告
  7. ACM_基础知识(二)
  8. 1.3 c++程序的构成和书写形式
  9. 查看python安装位置和已安装库的相关操作
  10. html实现酷狗歌词,酷狗音乐怎么制作歌词?酷狗音乐制作歌词的方法
  11. 几分钟就可做出的酷炫PPT动画效果
  12. Win7 桌面右键一直转圈很慢
  13. 程序人生 - 给IT新人的15点建议:苦逼程序员的辛酸反省与总结
  14. 格局打开,外贸牛人的价格谈判策略!
  15. 江苏计算机对口单招本科学校,江苏对口单招本科学校
  16. win7重装的坑:启动分区不存在 使用分区工具修正
  17. SQL Server LocalDB本地文件数据库操作实践
  18. Neuroimaging 海外职位信息
  19. (矩阵Part2):矩阵进阶
  20. 批量修改图片名称(去掉原名字中的中文字符和空格)

热门文章

  1. Linux下能访问Nginx,本地无法访问
  2. android Mvp简单实用
  3. VC下使用Proc连接Oracle数据库
  4. javascript 常用的一些事件和应用
  5. 利用SuppressMessage来阻止FxCop进行代码分析时报出的警告
  6. lvds单8转双8芯片_单片机定时芯片方案开发,2到8小时可调定时IC,低功耗触发延时芯片sop-8封装-丽晶微电子...
  7. CCF201809-2 买菜
  8. 贪心算法——洛谷(P1803)
  9. Tensorflow——张量
  10. 解析markdown_利用 markdown 生成页面实践