最长公共子序列问题
Posted nuist__NJUPT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子序列问题相关的知识,希望对你有一定的参考价值。
最长公共子序列问题
由最长公共子序列的最优子结构性质可知,要找出X={x1,x2…xm}和Y={y1,y2…ym}的最长公共子序列,可以按照下列方式递归进行:
当x(m)=y(n)时,找出x(m-1)和y(m-1)的最长公共子序列,然后在其尾部加上x(m),即可得到X和Y的最长公共子序列。
当x(m)!=y(n)时,必须解两个子问题,即找出X(m-1)和Y的最长公共子序列,找出X与Y(n-1)的最长公共子序列,两者的最大值即为X和Y的最长公共子序列。
当X或者Y其中一个为空集,则最长公共子序列为0。
如下所示:第一个方法可以求出最长公共子序列的长度,同时记录每种情况,第二个方法根据情况进行递归求出最长公共子序列。
import java.util.Scanner;
public class LCS1 {
static int [][]helper = new int [10000][10000] ;
public static int longest(String s1, String s2){ //求出最长公共子序列的长度
int len1 = s1.length() ;
int len2 = s2.length() ;
int [][] dp = new int [len1+1][len2+1] ;
for(int i=1; i<=len1; i++){
dp[i][0] = 0 ;
}
for(int j=1; j<=len2; j++){
dp[0][j] = 0 ;
}
for(int i=1; i<=len1; i++){
for(int j=1; j<=len2; j++){
if(s1.charAt(i-1) == s2.charAt(j-1)){
helper[i][j] = 1;
dp[i][j] = dp[i-1][j-1] + 1 ;
}else if(dp[i-1][j] >= dp[i][j-1]){
helper[i][j] = 2 ;
dp[i][j] = dp[i-1][j] ;
}else{
helper[i][j] = 3 ;
dp[i][j] = dp[i][j-1] ;
}
}
}
return dp[len1][len2] ;
}
public static void lcs(int i, int j, String s1, String s2){ //找出最长公共子序列
if(i==0 || j==0){
return ;
}else if(helper[i][j] == 1){
lcs(i-1, j-1, s1, s2) ;
System.out.print(s1.charAt(i-1));
}else if(helper[i][j] == 2){
lcs(i-1, j, s1, s2);
}else if(helper[i][j] == 3){
lcs(i, j-1, s1, s2) ;
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
String s1 = input.next() ;
String s2 = input.next() ;
longest(s1, s2) ;
lcs(s1.length(), s2.length(), s1, s2) ;
}
}
以上是关于最长公共子序列问题的主要内容,如果未能解决你的问题,请参考以下文章