最长公共子序列
import java.util.Collections;
/**
* 最长公共子序列
* @author baolibin
用动态规划解决LCS
*/
public class _03_LCS {
public static void main(String[] args) {
String str1="sdebyjkdslsdgrteyb"; //测试一
String str2="bqwelsadfjjb";
LCSCommon lcsCommon = new LCSCommon(str1,str2);
lcsCommon.getCommonStr();
lcsCommon.strPrint();
String str3="qewrtuyijk"; //测试2
String str4="asdfghjk";
LCSCommon lcsCommon2 = new LCSCommon(str3,str4);
lcsCommon2.getCommonStr();
lcsCommon2.strPrint();
String str5="asdfgh"; //测试3
String str6="sdfgh";
LCSCommon lcsCommon3 = new LCSCommon(str5,str6);
lcsCommon3.getCommonStr();
lcsCommon3.strPrint();
}
}
class LCSCommon{
private String str1;
private String str2;
private StringBuilder strCom;
int[][] chose;
public LCSCommon(String str1,String str2){
this.str1=str1;
this.str2=str2;
strCom=new StringBuilder();
chose=new int[str1.length()+1][str2.length()+1];
}
/**
* 求最长公共子序列
*/
public void getCommonStr(){
char[] str_1=str1.toCharArray();
char[] str_2=str2.toCharArray();
int len1=str1.length();
int len2=str2.length();
for (int i = 1; i <=len1; i++) {//生成数组chose,数组chose记录序列Xi和Yi的最长公共子序列的长度
for(int j=1;j<=len2;j++){
if(str_1[i-1]==str_2[j-1]){
chose[i][j]=chose[i-1][j-1]+1;
}else {
if(chose[i][j-1]<chose[i-1][j]){
chose[i][j]=chose[i-1][j];
}else{
chose[i][j]=chose[i][j-1];
}
}
}
}
int i=len1;
int j=len2;
while (i!=0&&j!=0) { //根据生成的数组求最长公共子串
if (str_1[i-1]==str_2[j-1]) {
strCom.append(String.valueOf(str_1[i-1]).trim());
i--;
j--;
}else{
if(chose[i][j-1]>=chose[i-1][j]){
j--;
}else {
i--;
}
}
}
}
public void strPrint(){
if(strCom.toString().length()==0){
System.out.println("最长公共子序列为空");
return;
}
System.out.println("最长公共子序列为:"+strCom.reverse().toString());
}
}
结果:
最长公共子序列为:blsdb
最长公共子序列为:jk
最长公共子序列为:sdfgh
同样会出现多解问题,比如 abgh和agbh 会有两个解。。
要所有的解,就要把所有结果都遍历一下