動態規劃之最長公共子序列算法

動態規劃之最長公共子序列算法

算法思想:
假設X = (x1, x2, ..., xm), Y = {y1, y2, ..., yn)的最長公共子序列爲Z = (z1. z2, ..., zk).
則:
1.若xm = yn, 則zk = xm = yn,且Zk-1是Xm-1和Yn-1的最長公共子序列;
2.若xm != yn, 且zk != xm, 則Z是Xm-1和Y的最長公共子序列;
3.若xm != yn, 且zk != yn, 則Z是X和Yn-1的最長公共子序列。
其中:Xm-1 = (x1, x2, ..., xm-1), Yn-1 = (y1, y2, ..., yn-1), Zk-1 = (z1, z2, ..., zk-1).

c[i][j]存儲的是Xi和Yj的最長公共子序列的長度,b[i][j]存儲的是c[i][j]的值是由哪一個子問題(如上3個子問題)的解得到的。

#include <stdio.h>

#define MAX 100
char x[MAX+1], y[MAX+1];
int b[MAX+1][MAX+1], c[MAX+1][MAX+1], m, n;

static void init_xy(void);
static void lcs_length(void);
static void lcs(int i, int j);
int main(int argc, char **argv)
{
        init_xy();
        lcs_length();

        printf("The lowest common subsequence is: ");
        lcs(m, n);
        printf("/n");

        return 0;
}

static void init_xy(void)
{
        int i;

        printf("Please input two sequences numbers: ");
        scanf("%d %d", &m ,&n);
        getchar();

        printf("Please input two sequences:/n");
        for(i = 1; i <= m; i++){
                scanf("%c", &x[i]);
        }
        getchar();
        for(i = 1; i <= n; i++){
                scanf("%c", &y[i]);
        }
        getchar();
}

static void lcs_length(void)
{
        int i, j;

        for(i = 1; i <= m; i++){
                for(j = 1; j <= n; j++){
                        if(x[i] == y[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] = 2;
                        }
                        else{
                                c[i][j] = c[i][j-1];
                                b[i][j] = 3;
                        }
                }
        }
        printf("The lowest common subsequence lenght = %d/n", c[m][n]);
}

static void lcs(int i, int j)
{
        if(i == 0 || j == 0){
                return;
        }

        if(b[i][j] == 1){
                lcs(i-1, j-1);
                printf("%c ", x[i]);
        }
        else if(b[i][j] == 2){
                lcs(i-1, j);
        }
        else{
                lcs(i, j-1);
        }
}

執行結果:

[xxxx@localhost suanfa]$ ./a.out
Please input two sequences numbers: 7 6
Please input two sequences:
ABCBDAB
BDCABA
The lowest common subsequence lenght = 4
The lowest common subsequence is: B C B A

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章