求最长公共子序列,输出路径,a[i][j]为到第i行第j列时最长的公共子序列,所以在输出路径的时候,讲a[cnt1][cnt2]从后遍历排除不是的情况,再用path记录路径就可以。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
string str1[101], str2[101], s, path[101];
int a[101][101],cnt1, cnt2;
int LCS ( string *str1, string *str2 ) {
memset ( a, 0, sizeof ( a ) );
for ( int i = 1; i <= cnt1; ++i )
for ( int j = 1; j <= cnt2; ++j ) {
if ( str1[i] == str2[j] ) a[i][j] = a[i - 1][j - 1] + 1;
else a[i][j] = max ( a[i][j - 1], a[i - 1][j] );
}
return a[cnt1][cnt2];
}
int main ( ) {
//freopen ( "input.txt", "r", stdin );
//freopen ( "output.txt", "w", stdout );
while ( cin >> s ) {
cnt1 = 0, cnt2 = 0;
while ( 1 ) {
if ( s != "#" ) str1[++cnt1] = s;
else break;
cin >> s;
}
while ( 1 ) {
cin >> s;
if ( s != "#" ) str2[++cnt2] = s;
else break;
}
int ans = LCS ( str1, str2 );
int tmp = ans;
while ( a[cnt1][cnt2] ) {
if ( a[cnt1][cnt2] == a[cnt1 - 1][cnt2] ) cnt1--;
else if ( a[cnt1][cnt2] == a[cnt1][cnt2 - 1] ) cnt2--;
else {
path[tmp--] = str1[cnt1];
cnt1--; cnt2--;
}
}
bool flag = 1;
for ( int i = 1; i <= ans; ++i )
if ( flag ) cout << path[i].c_str ( ), flag = 0;
else cout << " " << path[i].c_str ( );
cout << endl;
}
}