`
lovnet
  • 浏览: 6710056 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

求两个字符串最长公共子串LCS

 
阅读更多

LCS(Longest Common Subsequence) 就是求两个字符串最长公共子串的问题。

比如:

String str1 = new String("adbccadebbca");
String str2 = new String("edabccadece");
str1与str2的公共子串就是bccade.

解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.

下面是字符串21232523311324和字符串312123223445的匹配矩阵,前者为X方向的,后者为Y方向的。不难找到,红色部分是最长的匹配子串。通过查找位置我们得到最长的匹配子串为:21232


  0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
  0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
  1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
  0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
  1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
  0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
  1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
  1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
  0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
  0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
但是在0和1的矩阵中找最长的1对角线序列又要花去一定的时间。通过改进矩阵的生成方式和设置标记变量,可以省去这部分时间。下面是新的矩阵生成方式:
  0 0 0 1 0 0 0 1 1 0 0 1 0 0 0
  0 1 0 0 0 0 0 0 0 2 1 0 0 0 0
  1 0 2 0 1 0 1 0 0 0 0 0 1 0 0
  0 2 0 0 0 0 0 0 0 1 1 0 0 0 0
  1 0 3 0 1 0 1 0 0 0 0 0 1 0 0
  0 0 0 4 0 0 0 2 1 0 0 1 0 0 0
  1 0 1 0 5 0 1 0 0 0 0 0 2 0 0
  1 0 1 0 1 0 1 0 0 0 0 0 1 0 0
  0 0 0 2 0 0 0 2 1 0 0 1 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
  0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
当字符匹配的时候,我们并不是简单的给相应元素赋上1,而是赋上其左上角元素的值加一。我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。

  这样做速度比较快,但是花的空间太多。我们注意到在改进的矩阵生成方式当中,每生成一行,前面的那一行就已经没有用了。因此我们只需使用一维数组即可。最终的代码如下:

publicclassLCString2...{

publicstaticvoidgetLCString(char[]str1,char[]str2)
...{
inti,j;
intlen1,len2;
len1
=str1.length;
len2
=str2.length;
intmaxLen=len1>len2?len1:len2;
int[]max=newint[maxLen];
int[]maxIndex=newint[maxLen];
int[]c=newint[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(intk=1;k<maxLen;k++)
...{
max[k]
=0;
maxIndex[k]
=0;
}

}

elseif(c[j]==max[0])
...{//有多个是相同长度的子串
for(intk=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(
"");
}

}

}


publicstaticvoidmain(String[]args)...{

Stringstr1
=newString("adbba1234");
Stringstr2
=newString("adbbf1234sa");
getLCString(str1.toCharArray(),str2.toCharArray());
}

}

分享到:
评论

相关推荐

    LCS最长公共子串

    c源码编写的求两个字符串的最长公共子串,采用递归算法

    深入解析最长公共子串

    请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。 分析...

    LCS(longest common substring)算法,即最大公共子串 C实现

    LCS(longest common substring)算法,即最大公共子串,它是求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长...

    详解Python最长公共子串和最长公共子序列的实现

    LCS问题就是求两个字符串最长公共子串的问题。解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1的序列,其对应的位置就是最长匹配子串的位置...

    C语言求解最长公共子字符串问题及相关的算法分析

    请编写一个函数,输入两个字符串,求它们的最长公共子序列,并打印出最长公共子序列。 例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子...

    PHP实现求解最长公共子串问题的方法

    请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出一个最长公共子串。 例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串, 下面的算法是根据网上的java算法由酒逍遥 ...

    lcs.rar_ateh8z_lcs问题_最长公共子序列;动态规划;计算生物学;

    LCS问题就是求两个字符串最长公共子串的问题。解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1的序列,其对应的位置就是最长匹配子串的位置...

    LCS:LCS 类比较两个文本文件并找到最长公共子串 (LCS)。 这是通过使用自定义 String 类模拟字符串在旧版本 Java 中的行为方式来实现的

    LCS 类比较两个文本文件并找到最长公共子串 (LCS)。 这是通过使用自定义 String 类模拟字符串在旧版本 Java 中的行为方式来实现的 此代码用于通过命令行比较两个文本文件并返回两者共享的最长公共子字符串。 对于这...

    最长公共子序列

    如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。...本资源编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。

    java笔试题回文子串-LPS-LCS-Algorithm-Analysis:最长公共子串的实现及相关问题

    情况,此可视化的两个字符串长度相等。 设置 Java 源代码需要 Java 8 或更高版本; 此外,测试代码使用 JUnit 4.12,因此必须使用 Maven 或其他首选方法将其添加到项目中。 包含 Python 可视化代码并需要 MatPlotLib...

    1_金策_字符串算法选讲.pdf

    在 O(n log n) 时间空间预处理后(或较复杂的 O(n) 时间空间 预处理), 可以 O(1) 回答: 两个子串的最长公共前缀 (LCP)、最 长公共后缀 (LCS)。 对于拥有周期 p 的串 s, LCP(s[1..n], s[1 + p..n]) = n − p。 输入 ...

    我用Python写的一些算法

    计算集合中两个元素的和和一个数相等 ##动态规划 使用分治法的最大子数组(应该算成分治法) 使用自底向上方法实现的最大子数组 使用动态规划的两种方式实现的LCS(最大公共串)(下面的算法都会使用动态规划的两种...

Global site tag (gtag.js) - Google Analytics