首先下意识想到的就是直接遍历两个字符串,相同的就存储起来,最终得到结果呗。
private static String LCS1(String str1, String str2) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
int len1,len2,i,j;
sb.delete(0, sb.length());
len1 = str1.length();
len2 = str2.length();
int tmp=0;
for(j=0;j<len1;j++){
for(i=tmp;i<len2;i++){
if(str1.charAt(j)==str2.charAt(i)){
sb.append(str2.charAt(i));
tmp = i+1;
break;
}
}
}
return sb.toString();
}
备份的递归方法,觉得最后的重构还是很好玩的,而且这种算法通用性比较强嘛,就实现一下呗。
package 动态规划;
import java.util.Scanner;
public class 最长公共子序列_备忘机制 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin = new Scanner(System.in);
String str1,str2;
while(cin.hasNext()){
str1 = cin.nextLine();
str2 = cin.nextLine();
int n1 = str1.length();
int n2 = str2.length();
int[][] c = new int[n1+1][n2+1];
for(int i=0;i<=n1;i++)
for(int j=0;j<=n2;j++){
if(i==0||j==0)
c[i][j] = 0;
else
c[i][j] = Integer.MIN_VALUE;
}
int[][] b = new int[n1+1][n2+1];
System.out.println(up_to_bottom_LCS(str1,str2,c,b,n1,n2));
printLCS(b, str1, n1,n2);
System.out.println();
}
}
private static void printLCS(int[][] b, String str1, int n1, int n2) {
// TODO Auto-generated method stub
if(n1==0||n2==0)
return;
if(b[n1][n2]==2){
printLCS(b, str1, n1-1, n2-1);
System.out.print(str1.charAt(n1-1));
}else if(b[n1][n2]==-1)
printLCS(b, str1, n1-1, n2);
else
printLCS(b, str1, n1, n2-1);
}
private static int up_to_bottom_LCS(String str1, String str2, int[][] c,
int[][] b, int n1, int n2) {
// TODO Auto-generated method stub
if(n1==0||n2==0)
return 0;
if(c[n1][n2]>Integer.MIN_VALUE)
return c[n1][n2];
if(str1.charAt(n1-1)==str2.charAt(n2-1)){
c[n1][n2] = up_to_bottom_LCS(str1, str2, c, b, n1-1, n2-1)+1;
b[n1][n2] = 2;
}else{
if(up_to_bottom_LCS(str1, str2, c, b, n1-1, n2)>up_to_bottom_LCS(str1, str2, c, b, n1, n2-1)){
c[n1][n2] = up_to_bottom_LCS(str1, str2, c, b, n1-1, n2);
b[n1][n2] = -1;
}else{
c[n1][n2] = up_to_bottom_LCS(str1, str2, c, b, n1, n2-1);
b[n1][n2] = 1;
}
}
return c[n1][n2];
}
}