如果我们记字符串Xi和Yj的LCS的长度为c[i,j],我们可以递归地求c[i,j]:
/ 0 if i<0 or j<0
c[i,j]= c[i-1,j-1]+1 if i,j>=0 and xi=xj
\ max(c[i,j-1],c[i-1,j] if i,j>=0 and xi≠xj
计算最长公共子序列长度的动态规划算法LCS_LENGTH(X,Y)以序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>作为输入。输出两个数组c[0..m ,0..n]和b[1..m ,1..n]。其中c[i,j]存储Xi与Yj的最长公共子序列的长度,b[i,j]记录指示c[i,j]的值是由哪一个子问题的解达到的,这在构造最长公共子序列时要用到。最后,X和Y的最长公共子序列的长度记录于c[m,n]中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include <cstdlib>
#include <iostream>
#include "iomanip.h"
#define max 100
using
namespace
std;
void
LCSLength(
int
m ,
int
n ,
char
*x ,
char
*y ,
char
b[][max] )
{
int
i , j , k;
int
c[max][max];
for
( i = 1 ; i <= m ; i++ )
{
c[i][0] = 0;
}
for
( i = 1 ; i <= n ; i++ )
{
c[0][i] = 0;
}
for
( i = 1 ; i <= m ; i++ )
{
for
( j = 1 ; j <= n ; j++ )
{
if
( x[i-1] == y[j-1] )
{
c[i][j] = c[i-1][j-1] + 1;
b[i][j] =
'\\'
;
}
else
if
( c[i-1][j] >= c[i][j-1] )
{
c[i][j] = c[i-1][j];
b[i][j] =
'|'
;
}
else
{
c[i][j] = c[i][j-1];
b[i][j] =
'-'
;
}
}
//for
printf
(
" "
);
for
( j = 1 ; j <= n ; j++ )
printf
(
"%2c"
,b[i][j]);
printf
(
"\n"
);
printf
(
"%2c"
,x[i-1]);
printf
(
"%2d"
,0);
for
( j = 1 ; j <= n ; j++ )
printf
(
"%2d"
,c[i][j]);
printf
(
"\n"
);
}
//for
printf
(
"\n"
);
}
void
LCS(
int
i ,
int
j ,
char
*x ,
char
b[][max])
{
if
( i == 0 || j == 0 ){
return
;}
if
( b[i][j] ==
'\\'
)
{
LCS( i - 1 , j - 1 , x , b);
cout<<x[i-1];
}
else
if
( b[i][j] ==
'|'
)
{
LCS( i - 1 , j , x , b );
}
else
{
LCS( i , j - 1 , x , b );
}
}
int
main()
{
char
x[max] = {
'e'
,
'g'
,
'c'
,
'r'
,
'b'
,
'a'
,
'd'
};
char
y[max] = {
'e'
,
'd'
,
'h'
,
'e'
,
'b'
,
'd'
};
int
m = 7;
int
n = 6;
char
b[max][max] = { 0 };
printf
(
" "
);
for
(
int
j = 1 ; j <= n ; j++ )
printf
(
"%2c"
,y[j-1]);
printf
(
"\n"
);
printf
(
" "
);
for
(
int
k = 1 ; k <= m ; k++ )
printf
(
"%2d"
,0);
printf
(
"\n"
);
LCSLength( m , n , x , y , b );
printf
(
"最长公共序列串为:"
);
LCS( m , n , x , b );
cout<<endl<<endl;
system
(
"PAUSE"
);
return
EXIT_SUCCESS;
}
|