一.蛮力搜索策略
蛮力搜索策略的步骤如下:
1.枚举序列XX里的每一个子序列xixi;
2.检查子序列xixi是否也是YY序列里的子序列;
3.在每一步记录当前找到的子序列里面的最长的子序列。
蛮力策略也叫做暴力穷举法,是所有算法中最直观的方法,但效率往往也是最差的。在第1步枚举XX中所有的子序列有2m2m个,每个子序列在YY中检查时间复杂度为O(n)O(n)。因此蛮力策略的最坏时间复杂度为O(n2m)O(n2m),这是指数级算法,对较长的序列求LCS是不适用的。
二.动态规划策略
LCS问题具有最优子结构
令 X=<x1,x2,…,xm>X=<x1,x2,…,xm> 和 Y=<y1,y2,…,yn>Y=<y1,y2,…,yn> 为两个序列,Z=<z1,z2,z3,…,zk>Z=<z1,z2,z3,…,zk>为XX和YY的任意LCS。则
如果xm=ynxm=yn,则zk=xm=ynzk=xm=yn且Zk−1Zk−1是Xm−1Xm−1和Yn−1Yn−1的一个LCS。
如果xm≠ynxm≠yn,那么zk≠xmzk≠xm,意味着ZZ是Xm−1Xm−1和YY的一个LCS。
如果xm≠ynxm≠yn,那么zk≠ynzk≠yn,意味着ZZ是XX和Yn−1Yn−1的一个LCS。
从上述的结论可以看出,两个序列的LCS问题包含两个序列的前缀的LCS,因此,LCS问题具有最优子结构性质。在设计递归算法时,不难看出递归算法具有子问题重叠的性质。
设C[i,j]C[i,j]表示XiXi和YjYj的最长公共子序列LCS的长度。如果i=0i=0或j=0j=0,即一个序列长度为00时,那么LCS的长度为0。
代码实现
#include <stdio.h>
#include <string.h>
#define MAXLEN 50
void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{
int i, j;
for(i = 0; i <= m; i++)
c[i]