算法学习笔记----最长公共子序列问题

来源:互联网 发布:淘宝上面买东西没发票 编辑:程序博客网 时间:2024/06/06 02:25

(说明:由于CSDN的博客中不能添加下标等特殊符号,所以部分内容使用截图的形式)


static void print_lcs(int **b, char *x, int i, int j){    int key;    if (i == 0 || j == 0) {        return;    }    key = b[i-1][j-1];    switch (key) {        case 0:            print_lcs(b, x, i - 1, j - 1);            printf("%c ", x[i-1]);            break;        case 1:            print_lcs(b, x, i - 1, j);            break;        case 2:            print_lcs(b, x, i, j - 1);            break;        default:            break;    }}static void lcs_length(char *x, int m, char *y, int n){    int b[m][n];    int *p[m];    int c[m+1][n+1];    int i,j;    for (i = 1; i <= m; ++i) {        c[i][0] = 0;    }    for (j = 0; j <= n; ++j) {        c[0][j] = 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-1][j-1] = 0;            } else if (c[i-1][j] >= c[i][j-1]) {                c[i][j] = c[i-1][j];                b[i-1][j-1] = 1;            } else {                c[i][j] = c[i][j-1];                b[i-1][j-1] = 2;            }        }    }    for (i = 0; i < m; ++i) {        p[i] = b[i];    }    print_lcs(p, x, m, n);    printf("\n");}

lcs_length()函数中前两个循环分别初始化为序列Y长度为0、序列X长度为0的情况。只要有一个序列的长度为0,则最大公共子序列的长度为0.接下来的两个嵌套循环用来计算X序列和Y序列长度不同时,最大公共子序列的长度,并存储计算最大子序列时选择的子问题最优解。
print_lcs()我们这里使用的是递归来实现,还可以使用循环来代替递归,提高效率。不过在使用循环时,要分配额外的空间来存储最大公共子序列,代码实现如下:
static void print_lcs(int **b, char *x, int i, int j, int length){    char lcs[length];    int k = length - 1;    do {        if (i == 0 || j == 0) {            break;        }        switch (b[i-1][j-1]) {            case 0:                lcs[k--] = x[i-1];                i = i - 1;                j = j - 1;                break;            case 1:                i = i - 1;                break;            case 2:                j = j - 1;                break;            default:                break;        }    } while(1);    for (i = 0; i < length; ++i) {        printf("%c ", lcs[i]);    }}
 参数中的length就是X序列和Y序列最大公共子序列的长度,可以计算完c数组和b数组之后,通过c[m][n]获取。


原创粉丝点击