首页 > 代码库 > UVA531- Compromise

UVA531- Compromise

题意:找出两个文本的最长公共子序列,输出序列


思路:最长公共子序列(LCSL),使用标记数组,递归输出最长公共子序列。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 105;

char s1[MAXN][MAXN], s2[MAXN][MAXN], s[MAXN];
int d[MAXN][MAXN], path[MAXN][MAXN];
int cnt1, cnt2, flag;

void init() {
    cnt1 = 0;
    strcpy(s1[cnt1++], s);    
    while (scanf("%s", s1[cnt1])) {
        if (strcmp(s1[cnt1], "#") == 0) 
            break;
        cnt1++; 
    } 
    cnt2 = 0;
    while (scanf("%s", s2[cnt2])) {
        if (strcmp(s2[cnt2], "#") == 0) 
            break;
        cnt2++; 
    } 
    flag = 0;
}

void LCSL(int l1, int l2) {
    memset(d, 0,sizeof(d));
    for (int i = 1; i <= l1; i++) {
        for (int j = 1; j <= l2; j++) {
            if (strcmp(s1[i - 1], s2[j - 1]) == 0) {
                d[i][j] = d[i - 1][j - 1] + 1;  
                path[i][j] = 1;
            }
            else {
                if (d[i - 1][j] > d[i][j - 1]) {
                    d[i][j] = d[i - 1][j];
                    path[i][j] = 0;
                }
                else {
                    d[i][j] = d[i][j - 1];
                    path[i][j] = -1;
                }    
            }
        }  
    }
}

void outPut(int i, int j) {
    if (!i || !j)
        return;
    if (path[i][j] == 1) {
        outPut(i - 1, j - 1);
        if (flag)
            printf(" ");
        else
            flag = 1; 
        printf("%s", s1[i - 1]); 
    }
    else if (path[i][j] == 0)
        outPut(i - 1, j);
    else
        outPut(i, j - 1);
}

int main() {
    while (scanf("%s", s) != EOF) {
        init();
        LCSL(cnt1, cnt2);    
        outPut(cnt1, cnt2);
        printf("\n");
    }
    return 0;
}


UVA531- Compromise