最长共公共子序列
![](https://img2022.cnblogs.com/blog/411706/202205/411706-20220503182216083-1180209500.png)
公式的含义就是:假设两个字符串A[10]和B[100]的最后一个字符相等,那最长子序列 = A[9]和B[99]的最长子序列的长度+1;
如果A和B的最后一个字符不相等,那可能A[1~10]和B[1~99]有最长组序列;也可能 A[1~9]与B[1~100]有最长子序列;(我们假设下标以及数据都从1开始)
1记录二维数组的每个位置的值之后,取右下角的值作为最长公共子序列的值
2子序列是一个有序,但是不一定连续的序列:
3如ABCD 与AEFDB的最长公共子序列:AD or AB
4求最长公共子序列,就是一个利用上述公式,填表的过程
按公式直接写方法1:
int LCS(char*A, char*B,int ilen,int jlen) { if (ilen <0 || jlen <0) { return 0; } else if (A[ilen] == B[jlen]) { return LCS(A,B ,ilen-1,jlen-1) + 1; } else if (A[ilen] != B[jlen]) { return max(LCS(A,B,ilen-1,jlen),LCS(A,B,ilen,jlen-1)); } } int main() { char A[3] = {'a','c','d'}; char B[3] = {'a','b','c'}; int i = 2;//0,1,2;三个数下标从0开始,下标2是第三个数字 int j = 2;// int maclen = LCS(A, B, i, j); return 0; }
按公式正向建表方法二:
int LCS(char*A, char*B,int ilen,int jlen,int c[][5]) { for (size_t i = 0; i <= ilen; i++) { for (size_t j = 0; j <= jlen; j++) { if (i == 0 || j == 0) { c[i][j] = 0; } else if (A[i-1] == B[j-1])//A,B的数据是从下标0开始的 { c[i][j] = c[i-1][j-1]+1; } else { c[i][j] = max(c[i][j - 1],c[i-1][j]); } } }
return c[ilen][jlen]; } int main() { char A[3] = {'a','c','d'}; char B[4] = {'a','b','c','e'}; int i = 3;//A 有3个数据 int j = 4;//B 有四个数据 int c[4][5] = { 0 };//建表,表的右下角的值就是最终我们要的值(第一行和第一列是0) int maxlen = LCS(A, B, i, j,c);//2 return 0; }