1、填值,递增填
·长度分别为m=len1+1和n=len2+1;
·创建1个二维数组L[m.n];
·初始化L数组内容为0
· i和j分别从1开始,i++,j++循环:
- 如果str1[i] == str2[j],则L[i,j] = L[i - 1, j -1] + 1;
- 如果str1[i] != str2[j],则L[i,j] = max{L[i,j - 1],L[i - 1, j]}
·最后从L[i,j]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
·从数组L中找出一个最长的公共子序列
2、返回路线,从数组L中查找一个最长的公共子序列
.i和j分别从m-1,n-1开始,递减循环直到i = 1,j = 1。其中,m和n分别为两个串的长度。
·如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i--,j--;
·长度分别为m=len1+1和n=len2+1;
·创建1个二维数组L[m.n];
·初始化L数组内容为0
· i和j分别从1开始,i++,j++循环:
- 如果str1[i] == str2[j],则L[i,j] = L[i - 1, j -1] + 1;
- 如果str1[i] != str2[j],则L[i,j] = max{L[i,j - 1],L[i - 1, j]}
·最后从L[i,j]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
·从数组L中找出一个最长的公共子序列
2、返回路线,从数组L中查找一个最长的公共子序列
.i和j分别从m-1,n-1开始,递减循环直到i = 1,j = 1。其中,m和n分别为两个串的长度。
·如果str1[i] == str2[j],则将str[i]字符插入到子序列内,i--,j--;
·如果str1[i] != str[j],则比较L[i,j-1]与L[i-1,j],L[i,j-1]大,则j--,否则i--;(如果相等,则任选一个)
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str1 = "ABCBDAB";
String str2 = "BDCABA";
System.out.println(getLongestCommonSubSquence(str1,str2));
}
public static String getLongestCommonSubSquence(String s1,String s2){
int length1=s1.length();
int length2=s2.length();
int m=length1+1;
int n=length2+1;
int[][] L=new int[m][n]; //初始化一个(length1+1)*(length2+1)的二维数组
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
L[i][j]=0;
}
}
/*第一步填值 s1[i]和s2[j]比较确定L[i][j]
* 相等:对角线+1
* 不等:两边最大值
* */
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(s1.charAt(i-1)==s2.charAt(j-1)){
L[i][j]=L[i-1][j-1]+1;//相等:对角线+1
}
else {//不等:两边最大值
L[i][j]=L[i][j-1]>L[i-1][j]?L[i][j-1]:L[i-1][j];
}
}
}
/*第二步,取返回值,s1[i]和s2[j]比较
* 相等:走对角线,i--,j--,保存s1[i]或s2[j]
* 不等:走两边值大的,比较L[i-1][j]和L[i][j-1],若L[i][j-1]大,j--,
* */
StringBuffer sb=new StringBuffer();
for(int i=m-1,j=n-1;i>=1&&j>=1;){
if(s1.charAt(i-1)==s2.charAt(j-1)){
sb.append(s1.charAt(i-1));//倒序打印的
i--;
j--;
}
else{
if(L[i][j-1]>L[i-1][j]){
j--;
}
else {
i--;
}
}
}
sb.reverse();//反转就变成正序了
return sb.toString();//正序打印的
}
}