运用动态规划思想:
https://blog.csdn.net/u013921430/article/details/79299678
1)最长公共子序列的长度的动态规划方程
设有字符串a[0...n],b[0...m],下面就是递推公式。字符串a对应的是二维数组num的行,字符串b对应的是二维数组num的列。
2)
String left="helloword";
String right="llowor";
代码:
package com.parse;
public class Test3 {
public static void main(String args[]){
String left="helloword";
String right="lloworfff";
//打印动态规划的数组
System.out.println("打印动态规划的数组:");
int[][] dp=longestCommonSubstringLengthArray(left,right);
for(int i=0;i<left.length()+1;i++) {
for (int j = 0; j < right.length()+1; j++) {
System.out.print("\t"+dp[i][j]);
}
System.out.println();
}
//打印最长公共子序列
System.out.println();
System.out.println("打印最长公共子序列:\t"+longestCommonSubsequence(left,right));
//打印最长公共子序列长度
System.out.println();
System.out.println("打印最长公共子序列长度:\t"+apply(left,right));
}
//计算最长公共子序列长度
public static Integer apply(final CharSequence left, final CharSequence right) {
if (left == null || right == null) {
throw new IllegalArgumentException("Inputs must not be null");
}
return longestCommonSubsequence(left, right).length();
}
//获取最长公共子序列
public static CharSequence longestCommonSubsequence(final CharSequence left, final CharSequence right) {
// Quick return
if (left == null || right == null) {
throw new IllegalArgumentException("Inputs must not be null");
}
final StringBuilder longestCommonSubstringArray = new StringBuilder(Math.max(left.length(), right.length()));
//获取动态规划数组
final int[][] lcsLengthArray = longestCommonSubstringLengthArray(left, right);
//下面是通过数组返回的公共字符串,从后向前计算,然后再反转
int i = left.length() - 1;//行-1,此处i,j为数组的右下角倒数一个,为打印出来的5
int j = right.length() - 1;//列-1
int k = lcsLengthArray[left.length()][right.length()] - 1;//此处为5
while (k >= 0) {
if (left.charAt(i) == right.charAt(j)) {
longestCommonSubstringArray.append(left.charAt(i));
i = i - 1;
j = j - 1;
k = k - 1;
} else if (lcsLengthArray[i + 1][j] < lcsLengthArray[i][j + 1]) {
//如果该点下边小于该点右边,在数组中(行减一,向上走),在left字符串中,向左走一位
//右边大是left不匹配,要减去left的一位
i = i - 1;
} else {
//如果该点下边小于该点右边,在数组中(列减一,向左走),在right字符串中,向左走一位
//下边大是right不匹配,要减去right的一位
j = j - 1;
}
}
return longestCommonSubstringArray.reverse().toString();
}
//获取最长公共子序列数组
public static int[][] longestCommonSubstringLengthArray(final CharSequence left, final CharSequence right) {
final int[][] lcsLengthArray = new int[left.length() + 1][right.length() + 1];
for (int i = 0; i < left.length(); i++) {
for (int j = 0; j < right.length(); j++) {
if (i == 0) {
lcsLengthArray[i][j] = 0;
}
if (j == 0) {
lcsLengthArray[i][j] = 0;
}
if (left.charAt(i) == right.charAt(j)) {
lcsLengthArray[i + 1][j + 1] = lcsLengthArray[i][j] + 1;
} else {
lcsLengthArray[i + 1][j + 1] = Math.max(lcsLengthArray[i + 1][j], lcsLengthArray[i][j + 1]);
}
}
}
return lcsLengthArray;
}
}