LCS

#include <iostream>
using namespace std;

void LCS_Print(const char *X, const char *Y, int **R, int row, int col)  
{  
    if(R[row][col] == 1)    
    {  
        LCS_Print(X, Y, R, row-1, col-1);  
        cout << X[row-1];   
    }  
    else if(R[row][col] == 2)   
        LCS_Print(X, Y, R, row-1, col); 
    else if(R[row][col] == 3)    
        LCS_Print(X, Y, R, row, col-1);  
    else  
        return;  
}  

int LCS(const char *X, const char *Y)  
{  
    if(X == NULL || Y == NULL)  
        return 0;  

    int lenX = strlen(X);  
    int lenY = strlen(Y);  
    if(lenX == 0 || lenY == 0)  
        return 0;  

    int i, j;  
    int **C = new int *[lenX+1];    //记录长度  
    int **R = new int *[lenX+1];    //记录当前状态是由哪个状态变化来的
  
    for(i = 0; i <= lenX; i++)  
    {  
        C[i] = new int [lenY+1];  
        R[i] = new int [lenY+1];  
        for(j = 0; j <= lenY; j++)  
        {  
            C[i][j] = 0;  
            R[i][j] = 0;  
        }  
    }  

    for(i = 1; i <= lenX; i++)  
    {  
        for(j = 1; j <= lenY; j++)  
        {  
            if(X[i-1] == Y[j-1]) 
            {  
                C[i][j] = C[i-1][j-1] + 1;  
                R[i][j] = 1;   
            }  
            else  
            {  
                if(C[i-1][j] >= C[i][j-1])   
                {  
                    C[i][j] = C[i-1][j];  
                    R[i][j] = 2;    
                }  
                else    
                {  
                    C[i][j] = C[i][j-1];  
                    R[i][j] = 3;    
                }  
            }  
        }  
    }    

    LCS_Print(X, Y, R, lenX, lenY);   
    int lcs = C[lenX][lenY];  

    for(i = 0; i <= lenX; i++)  
    {  
        delete [] C[i];  
        delete [] R[i];  
    }  
    delete C;  
    delete R;  
    R = C = NULL;  
    cout << endl;
    return lcs;  
}  


int main()
{
    cout << LCS("abcbdab", "bdcaba") << endl;
    getchar();
    return 0;
}

或者如下实现:

#include <iostream>
using namespace std;
#define  MAXLEN 100

int dp[MAXLEN+1][MAXLEN+1];    // 存储LCS长度, 下标i,j表示序列X,Y长度 
char X[MAXLEN+1];
char Y[MAXLEN+1];
int i, j;
 
int main()
{
    char* X = "abcbdab";
    char* Y = "bdcaba";
    int xlen = strlen(X);
    int ylen = strlen(Y);

    // dp[0-xlen][0] & dp[0][0-ylen] 都已初始化0 
    for(i = 1; i <= xlen; ++i)
    {
        for(j = 1; j <= ylen; ++j)
        {
            if(X[i-1] == Y[j-1])
            {
                dp[i][j] = dp[i-1][j-1] + 1;
            }
            else if(dp[i][j-1] > dp[i-1][j])
            {
                dp[i][j] = dp[i][j-1];
            }
            else
            {
                dp[i][j] = dp[i-1][j];
            }
        }
    }
    printf("len of LCS is: %d\n", dp[xlen][ylen]);
 
    // 输出LCS 本来是逆序打印的,可以写一递归函数完成正序打印,这里采用的方法是将Y作为临时存储LCS的数组,最后输出Y
    i = xlen;
    j = ylen;
    int k = dp[i][j];
    char lcs[21] = {'\0'};
    while(i && j)
    {
        if(X[i-1] == Y[j-1] && dp[i][j] == dp[i-1][j-1] + 1)    //既然是公共子序列,两个都有,不妨利用X输出,此时X与Y字符相等
        {
            lcs[--k] = X[i-1];
            --i; --j;
        }
        else if(X[i-1] != Y[j-1] && dp[i-1][j] > dp[i][j-1])    //X跳过一个字符
        {
            --i;
        }
        else    //Y跳过一个字符
        {
            --j;
        }
    }
    printf("%s\n",lcs);
}













 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值