问题描述: 在最长公共子序列问题中,给定了两个序列 X=<X1, X2, ..., Xm>和Y=<Y1, Y2, ..., Yn>,希望找出X和Y的最大长度公共序列。
LCS是动态规划算法中比较经典的问题。
1、构造LCS的最优子结构:
设X=<X1, X2, ..., Xm>和Y=<Y1, Y2, ..., Yn>为两个序列,并设Z=<Z1, Z2, ..., Zk>为X何Y的任意一个LCS。
1)如果Xm = Yn,那么Zk=Xm=Yn而且Zk-1是Xm-1和Yn-1的一个LCS。
2)如果Xm != Yn,那么Zk != Xm蕴含Z是Xm-1和Y的一个LCS。
3)如果Xm != Yn,那么Zk != Ym蕴含Z是X和Yn-1的一个LCS。
2、一个递归解:
3、根据前两步,有了下面两种算法,第一种是比较简单且好理解的递归算法;第二种通过两个矩阵保存了动态规划的表格和最长公共子序列。
文件:"h1.1"
#ifndef H1_H
#define H1_H
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<process.h>
#include<math.h>
#define MAXSIZE 100
int LCS_LengthRecursive(char *s, int m, char *t, int n);
void LCS_Length(char *s, int m, char *t, int n, int c[][MAXSIZE], int b[][MAXSIZE]);
#endif
文件“LCS_Length.cpp"
#include "h1.h"
int LCS_LengthRecursive(char *s, int m, char *t, int n){
if(m==0 || n==0){
return 0;
}
else if(s[m] == t[n]){
return LCS_LengthRecursive(s, m-1, t, n-1)+1;
}
else{
return (LCS_LengthRecursive(s, m-1, t, n)>LCS_LengthRecursive(s, m, t, n-1))?
LCS_LengthRecursive(s, m-1, t, n):LCS_LengthRecursive(s, m-1, t, n-1);
}
}
void LCS_Length(char *s, int m, char *t, int n, int c[][MAXSIZE], int b[][MAXSIZE]){
int i, j;
for(i=0; i<=m; i++){
c[i][0] = 0;
}
for(j=1; j<=n; j++){
c[0][j] = 0;
}
for(i=1; i<=m; i++){ //As to b[i][j], when b[i][j]=0, means left;
for(j=1; j<=n; j++){ //when b[i][j]=1, means diagnoal; when b[i][j]=2, means up.
if(s[i] == t[j]){
c[i][j] = c[i-1][j-1] + 1;
b[i][j] = 1;
}
else if(c[i-1][j] >= c[i][j-1]){
c[i][j] = c[i-1][j];
b[i][j] = 0;
}
else{
c[i][j] = c[i][j-1];
b[i][j] = 2;
}
}
}
}
void PrintLCS(int b[][MAXSIZE], char *s, int m, int n){
if((m==0) || (n==0)){
return;
}
if(b[m][n] == 1){
PrintLCS(b, s, m-1, n-1);
printf("%c ", s[m]);
}
else if(b[m][n] == 0){
PrintLCS(b, s, m-1, n);
}
else{
PrintLCS(b, s, m, n-1);
}
}
int main(){
int c[MAXSIZE][MAXSIZE];
int b[MAXSIZE][MAXSIZE];
char *s = " cdfabcdefg";
char *t = " abcdefg";
LCS_Length(s, 10, t, 7, c, b);
printf("%d\n", c[10][7]);
PrintLCS(b, s, 10, 7);
return 0;
}
上述两个算法中,第一个算法即:LCS_LengthRecursive算法的时间复杂度为O( m+n )。
第二个算法即:LCS_Length的时间复杂度为O( mn )。