题意:给你两个单词序列,求出他们的最长公共子序列。
多组数据输入,单词序列长度<=100,单词长度<=30
因为所有组成LCS的单词都是通过 a[i] == b[j] 更新的。
打印序列的时候用mark标记一下,然后回溯找就可以了。
#include <iostream> #include <cstdio> #include <cstdlib> #include <vector> #include <map> #include <cstring> #include <string> using namespace std; #define maxn 150 vector<string> a, b, ans; int f[maxn][maxn], mark[maxn][maxn]; void printString(int i, int j) { if (i < 0 || j < 0) return; if (mark[i][j] == 0) { ans.push_back(a[i]); printString(i-1, j-1); } else if (mark[i][j] == 1) { printString(i, j-1); } else printString(i-1, j); } int main() { string s; while(cin >> s) { a.clear(); b.clear(); a.push_back(s); string t; while(cin >> t) { if (t == "#") break; a.push_back(t); } while(cin >> t) { if (t == "#") break; b.push_back(t); } int id = 0, n = a.size(), m = b.size(); memset(f, 0, sizeof(f)); memset(mark, 0, sizeof(mark)); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (a[i] == b[j]) { f[i][j] = f[i-1][j-1]+1; mark[i][j] = 0; } else if (f[i-1][j] > f[i][j-1]) { f[i][j] = f[i-1][j]; mark[i][j] = -1; } else { f[i][j] = f[i][j-1]; mark[i][j] = 1; } ans.clear(); printString(n-1, m-1); for (int i = ans.size()-1; i > 0; i--) cout << ans[i] << " "; cout << ans[0] << endl; } }