问题
如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。
注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。
请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。
例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,
则输出它们的长度4,并打印任意一个子串。
思想
求最长公共子串(Longest
Common Subsequence, LCS)是一道非常经典的动态规划题。
在开始想这道题之前应先理解什么是LCS(最长公共子串)。如串“abcbbc”,"abccbb",其中的一个字串"abc"是其公共子串,但不时最长公共字串。最长公共子串的定义中,并不要求最长公共子串必须连续出现在两个字符串中,只需要能保持顺序的出现在序列中即可。
在理解了什么是LCS之后,LCS的递归解就容易理解了:
c[i,j] =
0
(当 i=0或者j=0)
c[i-1,j-1] +1 (xi = yj,且 i>0,j>0)
Max(c[i,j-1], c[i-1,j]
) (xi!=yj , 且i, j >0 )
c[i,j]表示字符串 X[
1, i]和Y[1, j]的LCS长度。
算法导论给出了该算法。算法分成了两步。第一步找到LCS的长度。在找LCS长度的过程中,构造运算矩阵,以方便第二步求解LCS串。
扩展
LCS的定义不要求公共子串中的字符连续出现在两个字符串中。如果要求这样做。那么该怎么来做呢。
可以想到和LCS算法差不多的算法。即也维护一个M*N的矩阵c。如果a[i]==b[j],那么c[i][j]=c[i-1][j-1]+1;当i或者j等于0时,c[i][j]=1;如果不等c[i][j]=0。
代码实现参考代码2。
代码
package com.jy.string;
public class LCS {
public static void main(String[] args) {
char[] string = "abcbbc".toCharArray();
char[] string2 = "abccbb".toCharArray();
findLCS(string, string2);
}
/**
*
* @param string
* @param string2
*/
public static void findLCS(char[] string ,char[] string2) {
int m = string.length;
int n = string2.length;
int[][] c = new int[m+1][n+1];
int[][] b = new int[m+1][n+1];
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(string[i]==string2[j]) {
c[i+1][j+1]=c[i][j]+1;
b[i+1][j+1]= '\\';
} else {
if(c[i][j+1] >= c[i+1][j]) {
c[i+1][j+1] = c[i][j+1];
b[i+1][j+1]= '|';
} else {
c[i+1][j+1] = c[i+1][j];
b[i+1][j+1]= '-';
}
}
}
}
System.out.println("LCS长度:"+c[m][n]);
System.out.println("LCS序列:");
printLCS(b,string,m,n);
}
private static void printLCS(int[][] b, char[] string, int i, int j) {
if(i==0 || j==0) {
return ;
}
if(b[i][j]=='\\') {
printLCS(b, string, i-1, j-1);
System.out.println(string[i-1]);
} else if(b[i][j]=='|'){
printLCS(b, string, i-1, j);
} else {
printLCS(b, string, i, j-1);
}
}
}
package com.jy.string;
public class LCS2 {
public static void main(String[] args) {
findLCS("abcdefg".toCharArray(), "abcdged".toCharArray());
}
public static void findLCS(char[] string1, char[] string2) {
int m = string1.length;
int n = string2.length;
int[][] c = new int[m][n];
int max=0;
int maxPosX = 0;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(string1[i]==string2[j]) {
if(i==0||j==0) {
c[i][j] = 1;
} else {
c[i][j] = c[i-1][j-1]+1;
}
if(c[i][j]>max) {
max =c[i][j];
maxPosX = i;
}
} else {
c[i][j] = 0;
}
}
}
System.out.println(max);
for(int i = maxPosX-max+1;i<=maxPosX;i++) {
System.out.print(string1[i]);
}
}
}
分享到:
相关推荐
LCS(longest common substring)算法,即最大公共子串,它是求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长...
**最长公共子串(Longest Common Substring, LCS)**是两个或多个字符串中的最长字符串,该字符串同时也是这些字符串的子串。这里需要注意区分子串与子序列的概念。子串必须在原字符串中连续出现,而子序列则不必...
本话题聚焦于一个经典的算法问题——“查找最长公共子串”。这是一道典型的字符串算法题,主要考察对字符串操作和动态规划的理解。 首先,我们需要明确什么是“公共子串”。如果一个字符串s是另一个字符串t的子串,...
在编程领域,最长公共子串(Longest Common Substring,LCS)问题是一个经典的问题,主要涉及字符串处理和算法设计。在这个案例中,我们关注的是一个由C#实现的自创算法来解决这个问题。下面将详细讲解这个算法的...
### 最长公共子序列(Longest Common Subsequence, LCS) #### 定义与概念 最长公共子序列问题(LCS)是计算机科学中的一个经典问题,它涉及到在两个或多个序列中寻找最长的相同子序列。这里所说的“子序列”并不...
最长公共子串(Longest Common Substring,LCS)是一个在计算机科学中常见的字符串处理问题,它涉及到查找两个或多个字符串中的最长连续子序列,这个子序列同时存在于所有字符串中。MFC,全称为Microsoft Foundation...
在IT领域,尤其是在编程和算法设计中,"最长公共子串"是一个重要的概念。这个知识点主要涉及字符串处理和算法分析,对于计算机科学的学习者和开发者来说具有基础且实用的价值。在给定的压缩包文件中,我们可以看到它...
在编程领域,最长公共子串(Longest Common Substring,LCS)问题是一个经典的问题,它寻找两个或多个字符串中的最长连续子序列,这个子序列同时存在于所有字符串中。在这个问题中,我们专注于PHP如何解决两个字符串...
最长公共子字符串共有两种解决方法,下面具体说说我的思路方法一:Longest Common Substring和Longest Common Subsequence是有区别的X = <a>Y = <a>X和Y的Longest Common Sequence为,长度为4X和Y的Longest Common ...
在编程领域,"获取最长公共子串"是一个经典的问题,主要涉及到字符串处理和算法设计。这个问题的基本目标是从两个或多个给定的字符串中找到最长的共同连续子序列,即这个子序列是每个字符串的一部分,且在原字符串中...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一个经典的问题,主要涉及字符串处理和算法设计。在这个问题中,我们需要找到两个或多个字符串的最长子序列,这个子序列并不一定是连续的,但...
最长公共子序列(Longest Common Subsequence, LCS),顾名思义,是指在所有的子序列中最长的那一个。子串是要求更严格的一种子序列,要求在母串中连续地出现。在上述例子的中,最长公共子序列为blog(cnblogs, ...
Python中最长公共子串(Longest Common Substring, LCS)算法是一种寻找两个字符串共同子序列中长度最长的那个子串的方法。在本实例中,我们关注的是如何使用Python编写一个算法来实现这一功能。 首先,我们要了解...
数据结构问题:“最长回文子串问题”(Longest Palindromic Substring),详细解法和代码实现; 数据结构问题:“最长回文子串问题”(Longest Palindromic Substring),详细解法和代码实现; 数据结构问题:“最长...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要涉及字符串或序列的比较和分析。这个问题在文本编辑器的差异计算、生物信息学的DNA序列比对以及程序代码的相似性检测等多...
北大POJ2533-Longest Ordered Subsequence【O(nlogn)】
最长公用子串LCS服务器 最长公共子字符串(LCS)服务器概述构建一个简单的Web应用程序,允许用户在给定字符串列表的情况下请求最长公共子字符串。 功能要求通过HTTP POST解决最长的公共子字符串问题用户应该能够通过...