算法/动态规划/LongestCommonSubstring最长公共子串问题
来源:互联网 发布:胡琳 知乎 编辑:程序博客网 时间:2024/05/23 16:58
问题描述
最长公共子串跟LCS的区别在于这个子串要求在原字符串中是连续的,而最长公共子序列则并不要求连续
可以参考 LCS问题求解
动态规划求解
为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。
如果在什么想法都没有的情况下建个表,那我们会希望坐标轴上是两个子串,里面的内容是什么呢?比如可以这样,当字符不相等的时候记为0,不相等的记1,很好,那么最长对角线对应的就是最长子串!
b a b
c 0 0 0
a 0 1 0
b 1 0 1
a 0 1 0
但是在一个二维矩阵上找最长的 由1组成的斜对角线是不好实现的,可作如下改进:当要在矩阵中填1时,让它等于其左上角元素加1,这样不仅方便操作,还能get最长公共子串的长度,就是矩阵中的最大元素
b a b
c 0 0 0
a 0 1 0
b 1 0 2
a 0 2 0
然而,这个问题还是可以优化的:“在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵。”
这句话怎么理解呢?我们需要的只有一个最大长度和一个标记最大长度的位置,并不会再用到矩阵里其他的值,这样一来,只要记录完我们需要的,数据用完就可以丢掉了。具体的实现看代码
完整java代码如下:
public class LCSubstring { private static void printLCString(char[] str1, char[] str2) { int len1 = str1.length; int len2 = str2.length; int maxLen = len1 > len2 ? len1 : len2;// max[]记录最大长度// maxIndex[]记录最大长度对应的字符位置// c[]就是一维数组建立的"表格" 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; } } else { c[j] = 0; }// max[0]表示最先达到最大长度,对应maxIndex[0]// 如果发现与已存在的最大长度相等的,记在max[]数组的后面位置 if (c[j] == max[0]) { for (int k = 1; k < maxLen; k++) { if (max[k] == 0) { max[k] = c[j]; maxIndex[k] = j; break; } } }// 如果发现更大长度,首位置替换,后面清零 else 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; } } }// 打印c[]表格 for (int temp : c) { System.out.print(temp); } System.out.println(); }// 打印最长公共子串 for (j = 0; j < maxLen; j++) { if (max[j] > 0) { System.out.print("第" + (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 = "xzyzzyx"; String str2 = "zxyyzxz"; printLCString(str1.toCharArray(), str2.toCharArray()); String str3 = "MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCALLAAQANKESSSESFISRLLAIVAD"; String str4 = "MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCTLLAAQANKENSNESFISRLLAIVAG"; printLCString(str3.toCharArray(), str4.toCharArray()); }}
0 0
- 算法/动态规划/LongestCommonSubstring最长公共子串问题
- 算法回顾 - 动态规划 之 最长公共子串问题
- 【动态规划】最长公共子串问题
- 【动态规划】最长公共子串问题
- 最长公共子串问题 动态规划
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法解最长公共子序列LCS问题
- 算法知识之最长公共子序列问题(动态规划)
- 最长公共子序列问题(动态规划算法)
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法解最长公共子序列LCS问题
- java动态规划算法--最长公共子序列问题
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法之最长公共子序列问题
- 动态规划算法解最长公共子序列LCS问题
- 动态规划算法解最长公共子序列LCS问题
- Poedu_C_Lesson02_2_2017-4-21
- Mac下安装配置Homebrew图文教程
- resource处理动态数据交互
- k8s安装
- 【laravel】laravel的下载&安装
- 算法/动态规划/LongestCommonSubstring最长公共子串问题
- 根据先序遍历和中序遍历,打印层序遍历
- DOM对象
- H5基础知识第六课时(CSS)1
- SSL 2289——庆功会
- Logback和Logstash的集成
- CentOS下升级Git1.7.1升级到Git2.2.1
- NSOJ 大数阶乘
- JavaScript之值类型和引用类型的区别