看一个例子:S1={1,5,2,8,9,3,6},S2={5,6,8,9,3,7},其最长公共子序列为{5,8,9,3}。
注意:最长公共子串和最长公共子序列是不同的。顾名思义,前者必须是连续的,后者只要求顺序一样即可。下链接是最大公共子串的链接。
第八届蓝桥杯省赛——6最大公共子串(二维数组)_蓝桥杯最大公共子串_W少年没有乌托邦的博客-CSDN博客
分析:
跟最大公共子串不同的是最大公共子序列是不需要连着就可以当作连着的,所以在代码中体现的差别就是,最大公共子序列多两个条件,下图中是二维数组的表格化,我们发现当字母对不起来的时候,格点中的值依然会继承上一行和左边的最大值(即已经匹配了的最大公共子序列长度)。子序列多出来的两句话就是当字母不相等时,该点就等于上一行的最大值及左边格点的最大值相对最大的那个。二维数组的所有值填完之后遍历并找到这个二维数组所有格子中最大的值就是最大公共子序列的长度
![](https://img-blog.csdnimg.cn/img_convert/d40e0a57b71343020eca2883e5110e93.png)
下图是求最大公共子序列的过程
![](https://img-blog.csdnimg.cn/img_convert/fe274fabfe5b0c9132c87565f73c28ba.png)
package 历届真题省赛阶段;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class 测试1 {
public static void main(String[] args) {
String a = "ABCBDAB";
String b = "BDCABA";
int v= f(a, b);
System.out.println(v);
}
private static int f(String a, String b) {
char[] c1 = a.toCharArray();
char[] c2 = b.toCharArray();
int zu[][] = new int[c1.length + 1][c2.length + 1];
for (int i = 1; i < zu.length; i++) {
for (int j = 1; j < zu[i].length; j++) {
if (c1[i - 1] == c2[j - 1]) {
zu[i][j] = zu[i - 1][j - 1] + 1;
} else if (zu[i][j - 1] > zu[i - 1][j]) {
zu[i][j] = zu[i][j - 1];
} else {
zu[i][j] = zu[i - 1][j];
}
}
}
int max = 0;
for (int i = 1; i < zu.length; i++) {
for (int j = 1; j < zu[i].length; j++) {
if (zu[i][j] > max) {
max = zu[i][j];
}
}
}
return max;
}
}