问题描述: LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列。
举例说明:比如,对于char x[]="aabcd";有顺序且相互相邻的aabc是其子序列,有顺序但是不相邻的abd也是其公共子序列。即,只要得出序列中各个元素属于所给出的数列,就是子序列。再加上char y[]="12abcabcd";对比出才可以得出最长公共子序列abcd。
array[i][j] -- 表示子串s1[0...i](数组长度为n)和子串s2[0...j](数组长度为m)的最长公共子序列
当s1[i] == s2[j]时,array[i][j] = array[i-1][j-1] + 1 公式1;
否则,array[i][j] = max(array[i-1][j], array[i][j-1]) 公式2;
/**
*
* @param s1 第一个字符序列
* @param length1 第一个字符序列的长度
* @param s2 第二个字符序列
* @param length2 第二个字符序列的长度
*/
public static void getlcs(String s1,int length1,String s2,int length2)
{
char[] x = s1.toCharArray();
char[] y = s2.toCharArray();
int[][] array = new int[length1+1][length2+1];
for(int i=0;i<length1+1;i++){ // 将二维列表的第一例填为零
array[i][0]=0;
}
for(int j=0;j<length2+1;j++){ // 将二维列表的第一行填为零
array[0][j]=0;
}
for(int i=0;i<length1;i++){
for(int j=0;j<length2;j++){
if(x[i]==y[j]){
array[i+1][j+1]=array[i][j]+1; // 此问题的第一个公式
}else {
array[i+1][j+1]=max(array[i+1][j],array[i][j+1]); //此问题的第二个公式
}
}
}
// 打印二维表格
for(int i=0;i<length1+1;i++){
for(int j=0;j<length2+1;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
Stack<Character> s = new Stack<Character>(); // 用栈从后向前存储最长子序列,打印出来正好是正向最长公共子序列
while (length1>0 && length2>0){
if (x[length1-1]==y[length2-1]){
s.push(x[length1-1]);
length1--;
length2--;
}else if(array[length1-1][length2]>array[length1][length2-1]){
length1--;
}else {
length2--;
}
}
while (!s.empty()){
System.out.print(s.pop());// 打印最长公共子序列
}
}
}
public static int max(int a, int b){//比较(a,b),输出大的值
return (a > b)? a : b;
}