Java——最长公共子串问题LCS

秒速五厘米 2022-06-17 00:07 329阅读 0赞

Java——最长公共子串问题LCS

求最长公共子序列(Longest Common Subsequence, LCS): 如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中, 则字符串一称之为字符串二的子串。 但是并不要求子串(字符串一)的字符必须连续出现在字符串二中。

采用一个二维矩阵来记录中间的结果。比如”abab”和”aba”,如果两个字符相等就在矩阵中填1

   a b  a  b

a  1  0  1 0

b  0  1  0 1

a  1  0  1 0

这样矩阵的斜对角线最长的那个就是最长公共子串“aba”。

为了直接得到矩阵中最长的对角线,可以当要在矩阵填1时让它等于其左上角元素加1:

a b  a  b

a  1  0  1 0

b  0  2  0 2

a  1  0  3 0

这样矩阵中的最大元素就是最长公共子串的长度,而它所在的那条对角线就是最长公共子序列。下面是矩阵元素的计算公式:

20170411094959652

  1. package com.kexin.study2;
  2. public class LCS {
  3. public static void main(String[] args) {
  4. // 设置字符串长度
  5. int sublen1 = 5;
  6. int sublen2 = 6;
  7. // 随机生成字符串
  8. String str1 = "((ad)";
  9. String str2 = "(a((d)";
  10. //二位数组描述矩阵
  11. int[][] c = new int[sublen1 + 1][sublen2 + 1];
  12. // 动态规划计算所有子问题
  13. for (int i = sublen1 - 1; i >= 0; i--) {
  14. for (int j = sublen2 - 1; j >= 0; j--) {
  15. if (str1.charAt(i) == str2.charAt(j))
  16. c[i][j] = c[i + 1][j + 1] + 1;
  17. else
  18. c[i][j] = Math.max(c[i + 1][j], c[i][j + 1]);
  19. }
  20. }
  21. System.out.println("str1:" + str1);
  22. System.out.println("str2:" + str2);
  23. System.out.print("LCS:");
  24. int i = 0, j = 0;
  25. while (i < sublen1 && j < sublen2) {
  26. if (str1.charAt(i) == str2.charAt(j)) {
  27. System.out.print(str1.charAt(i));
  28. i++;
  29. j++;
  30. } else if (c[i + 1][j] >= c[i][j + 1])
  31. i++;
  32. else
  33. j++;
  34. }
  35. }
  36. }

发表评论

表情:
评论列表 (有 0 条评论,329人围观)

还没有评论,来说两句吧...

相关阅读

    相关 公共序列LCS问题

    好久没有写博客了,刚才在网上看了清华大学的数据结构公开课,链接:https://www.xuetangx.com 可以注册个账号去听数据结构课程,老师讲的特好。 我的代码是按

    相关 LCS 公共序列

    首先要明白什么是子序列,什么是子串; 设:主串长度为n; 子序列:从主串中抽出少于n的元素组成的序列(这些抽出的元素比一定是连续的他们的相对位置不变);