• 一个粗糙的打印两序列所有最大公共子序列的方法


    以下是典型动态算法打印两序列最大公共子序列的方法,该方法只能打印一个最大公共子序列:

     1 #include <iostream>
     2 using std::cout;
     3 using std::endl;
     4 
     5 const int NUM1=30,NUM2=30;
     6 char result[NUM1+1];
     7 int count=0;
     8 int lcsLength(char x[], char y[], int b[][NUM2+1],int m,int n) 
     9 {
    10     int c[NUM1+1][NUM2+1];
    11     for (int i = 0; i<=m; i++) 
    12         c[i][0]=0;
    13     for (int i = 0; i<=n; i++ ) 
    14         c[0][i]=0;
    15     for (int i = 1; i <= m; i++) 
    16     {
    17         for (int j = 1; j <= n; j++) 
    18         {
    19             if (x[i - 1]==y[j - 1])
    20             {
    21                 c[i][j]=c[i-1][j-1]+1; 
    22                 b[i][j]=1;
    23             }
    24             else 
    25                 if (c[i-1][j]>c[i][j-1]) 
    26                 {
    27                     c[i][j]=c[i-1][j]; 
    28                     b[i][j]=2;
    29                 }
    30                 else 
    31                 {
    32                     c[i][j]=c[i][j-1]; 
    33                     b[i][j]=3;
    34                 }
    35         }
    36     }
    37     return c[m][n];
    38 }
    39 
    40 void lcs(int i,int j, char x[], int b[][NUM2+1] ) 
    41 {
    42     if (i ==0 || j==0) 
    43         return;
    44 
    45     if(b[i][j]== 1) 
    46     {    
    47         lcs(i-1, j-1, x, b);
    48         cout<<x[i-1];
    49     }
    50     else 
    51         if(b[i][j] == 2)
    52             lcs(i-1, j, x, b);
    53         else 
    54             lcs(i, j-1, x, b);
    55 }
    56 
    57 int _tmain(int argc, _TCHAR* argv[])
    58 {
    59     char * x = "3123";
    60     char * y ="132";
    61     int xlen = strlen(x);
    62     int ylen = strlen(y);
    63     int b[NUM1 + 1][NUM2 + 1];
    64     int len = lcsLength( x, y, b, xlen,ylen );
    65     cout<<len<<endl;
    66     lcs( xlen,ylen, x, b);
    67 
    68     getchar();
    69     return 0;
    70 }

    只考虑最终的最优解,而不输出所有最优解或许是动态算法的很大的缺点。就这个问题,下面是一个粗糙的打印两序列所有最大公共子序列的方法:

     1 #include <iostream>
     2 using std::cout;
     3 using std::endl;
     4 
     5 const int NUM1=30,NUM2=30;
     6 char result[NUM1+1];
     7 int count=0;
     8 int lcsLength(char x[], char y[], int b[][NUM2+1],int m,int n) 
     9 {
    10     int c[NUM1+1][NUM2+1];
    11     for (int i = 0; i<=m; i++) 
    12         c[i][0]=0;
    13     for (int i = 0; i<=n; i++ ) 
    14         c[0][i]=0;
    15     for (int i = 1; i <= m; i++) 
    16     {
    17         for (int j = 1; j <= n; j++) 
    18         {
    19             if (x[i - 1]==y[j - 1])
    20             {
    21                 c[i][j]=c[i-1][j-1]+1; 
    22                 b[i][j]=1;
    23             }
    24             else 
    25                 if (c[i-1][j]>c[i][j-1]) 
    26                 {
    27                     c[i][j]=c[i-1][j]; 
    28                     b[i][j]=2;
    29                 }
    30                 else 
    31                     if(c[i-1][j]<c[i][j-1])
    32                     {
    33                         c[i][j]=c[i][j-1]; 
    34                         b[i][j]=3;
    35                     }
    36                     else
    37                     {
    38                         c[i][j]=c[i][j-1];    //或者c[i][j]=c[i-1][j];
    39                         b[i][j]=4;
    40                     }
    41         }
    42     }
    43     return c[m][n];
    44 }
    45 
    46 void lcs(int i,int j, char x[], int b[][NUM2+1],int idx,int len) 
    47 {
    48     if (i ==0 || j==0) 
    49     {
    50         for(int s=0;s<len;s++)
    51             cout<<result[s];
    52         cout<<endl;
    53         count++;
    54         return;
    55     }
    56     int t=b[i][j];
    57     if(b[i][j]== 1) 
    58     {    
    59         idx--;
    60         result[idx]=x[i- 1];
    61         lcs(i-1, j-1, x, b,idx,len);
    62     }
    63     else 
    64         if(b[i][j] == 2)
    65             lcs(i-1, j, x, b,idx,len);
    66         else 
    67             if(b[i][j]==3)
    68                 lcs(i, j-1, x, b,idx,len);
    69             else
    70             {
    71                 lcs(i,j-1,x,b,idx,len);
    72                 lcs(i-1,j,x,b,idx,len);
    73             }
    74 }
    75 
    76 int _tmain(int argc, _TCHAR* argv[])
    77 {
    78     char * x = "3123";
    79     char * y ="132";
    80     int xlen = strlen(x);
    81     int ylen = strlen(y);
    82     int b[NUM1 + 1][NUM2 + 1];
    83     int len = lcsLength( x, y, b, xlen,ylen );
    84     cout<<len<<endl;
    85     lcs( xlen,ylen, x, b,len,len );
    86     cout<<"共有:"<<count<<"";
    87     getchar();
    88     return 0;
    89 }
  • 相关阅读:
    合并排序二
    合并排序
    理解Windows消息循环机制
    直接插入排序
    关于typedef的用法总结
    迭代器的抽象
    C++基础--malloc和new的区别
    C++基础--sizeof和strlen的区别
    C++ VS编译问题--LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
    SSL--Windows下生成OpenSSL自签证书
  • 原文地址:https://www.cnblogs.com/kevinGaoblog/p/2491525.html
Copyright © 2020-2023  润新知