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,而是赋上其左上角元素的值加一。我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。
根据此理得到下列程序,考虑了可能会出现相同长度的子串,返回一个list
package com.parser.main;
import java.util.ArrayList;
import java.util.List;
//LCS算法实现 求两个字符串中间最长的公共字符串
public class Ss {
public static void main(String[] args) {
Ss ss = new Ss();
ss.getSameStr("12", "123pdg123");
}
public List<String> getSameStr(String str1, String str2){
char[] arrchar1 = str1.toCharArray();
char[] arrchar2 = str2.toCharArray();
int[][] arr = new int[arrchar1.length][arrchar2.length];
int len = arrchar1.length < arrchar2.length ? arrchar1.length:arrchar2.length;
int maxarr[] = new int[len];
int maxindex[] = new int[len];
for(int i = 0; i < arrchar1.length ; i++){
for(int j = 0; j < arrchar2.length ; j++){
if(arrchar2[j] == arrchar1[i]){
if(i == 0 || j == 0){
arr[i][j] = 1;
if(maxarr[0] < 1){
maxarr[0] = 1;
maxindex[0] = i;
}
}else{
arr[i][j] = arr[i-1][j-1] + 1;
//如果当前求出的子串长度大于了maxarr中第一个数值 则清空maxarr数值 全部置0 同时替换第一个最大值
if(maxarr[0] < arr[i][j]){
maxarr[0] = arr[i][j];
maxindex[0] = i;
for(int num = 1; num < maxarr.length; num++){
if(maxarr[num] == 0){
break;
}else{
maxarr[num] = 0;
maxindex[num] = 0;
}
}
}else if (maxarr[0] == arr[i][j]){
//如果当前求出的子串长度跟maxarr中第一个一致 则保留
int num = 0;
for(int max : maxarr){
if(max == 0){
maxarr[num] = arr[i][j];
maxindex[num] = i;
break;
}
num++;
}
}
}
}else{
arr[i][j] = 0;
}
}
}
for(int i = 0;i < arr.length ; i++){
for(int j = 0;j < arr[i].length;j++){
System.out.print(" " + arr[i][j]);
}
System.out.println("");
}
List<String> list = new ArrayList<String>();
for(int i = 0; i< maxarr.length ;i++){
if(maxarr[i] == 0){
break;
}
int num = maxindex[i] - (maxarr[i] -1);
String str = "";
for(int k = 0;k<maxarr[i];k++){
char tempchar = arrchar1[num];
str += String.valueOf(tempchar);
num++;
}
System.out.println(str);
list.add(str);
}
return list;
}
}
output:
1 0 0 0 0 0 1 0 0
0 2 0 0 0 0 0 2 0
12
12
分享到:
相关推荐
最长公共字串算法,为算法导论上的算法,可以运行,运行时间为O(mn)
在两个给定的字符串中,LCS是指不考虑字符顺序的最长子串,它同时存在于这两个字符串中。这个问题在Java编程中常用于算法训练和实际应用。 LCS问题可以通过动态规划来解决。动态规划是一种解决最优化问题的数学方法...
**最长公共子串(Longest Common Substring, LCS)**是两个或多个字符串中的最长字符串,该字符串同时也是这些字符串的子串。这里需要注意区分子串与子序列的概念。子串必须在原字符串中连续出现,而子序列则不必...
在MFC环境下实现最长公共子串,我们可以创建一个可视化的应用程序,用户可以输入两个或多个字符串,然后程序通过算法找出并显示最长公共子串。MFC的框架提供了一个方便的方式来构建这样的图形用户界面(GUI),包括...
根据LCS算法取出最长公用字符串,实现字符串比较
**最长公共子序列(Longest Common Subsequence, LCS)算法详解** 在计算机科学中,LCS算法是一个经典的字符串处理问题,用于寻找两个序列的最长子序列,这个子序列不必是连续的,但必须保持原序列的相对顺序。该...
最长公共子串是指在两个或多个字符串中,存在一个子串,它在每个字符串中都出现,并且长度最长。这里的“子串”指的是连续的字符序列。 2. **算法原理**: LCS算法通常基于动态规划思想来解决。我们可以创建一个...
c源码编写的求两个字符串的最长公共子串,采用递归算法
在计算机科学领域,尤其是在数据处理与算法设计方面,“最长公共子串”(Longest Common Substring, LCS)是一个非常重要的概念。该问题主要涉及到两个或多个字符串之间共同拥有的最长连续字符序列的寻找。这种应用...
关于LCS(最长公共子序列)算法的实现~ 自己测试通过的
最长公共子序列(Longest Common Subsequence,LCS)算法是一种经典的计算机科学问题,主要应用于比较和分析两个或多个序列的相似性。在文本编辑、生物信息学、数据挖掘等领域有着广泛的应用。LCS问题的基本目标是...
LCS(longest common substring)算法,即最大公共子串,它是求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长...
Python中最长公共子串(Longest Common Substring, LCS)算法是一种寻找两个字符串共同子序列中长度最长的那个子串的方法。在本实例中,我们关注的是如何使用Python编写一个算法来实现这一功能。 首先,我们要了解...
最长子序列LCS算法,用于处理最长公共字串问题。 两个序列的LCS问题包含两个序列的前缀的LCS,因此,LCS问题具有最优子结构性质。在设计递归算法时,不难看出递归算法具有子问题重叠的性质。 设C[i,j]C[i,j]...
如果两个字符串的首字符不相等,则用三种对齐策略分别计算可能的最长公共子串,然后取最长的一个与当前已知的最长公共子串比较,如果比当前已知的最长公共子串长就用计算出的最长公共子串代替当前已知的最长公共子串...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要应用于比较和分析两个或多个序列的相似性。在这个问题中,目标是找到两个序列的最长子序列,这个子序列不需要在原序列中...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一个经典的问题,主要涉及算法和数据结构领域,特别是在字符串处理、生物信息学和比较编程中有着广泛的应用。LCS问题寻找的是两个序列中长度...
总的来说,通过理解LCS的概念、动态规划的原理以及Java代码的实现,我们可以有效地解决两个序列的最长公共子序列问题,并将其应用于序列比对、文本编辑距离计算等多个领域。学习和掌握这种算法对于提升编程能力和...
在这个C++算法实验中,我们关注的是如何找到两个字符串之间的最长公共子序列,而不仅仅是子串。子序列不必连续,只要在原序列中存在即可。 **LCS算法原理:** LCS算法基于动态规划思想,通过构建一个二维数组来...
实现了求最长公共子序列的算法,内容简单易懂,代码也很短