最长公共子串(子串的顺序可以不相连)

如果我们记字符串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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值