最長公共子序列,即Longest Common Subsequence,LCS。一個序列S任意刪除若干個字符獲得新序列T,則T叫作S的子序列;兩個序列X和Y的公共子序列中,長度最長的那個,定義爲X和Y的最長公共子序列。字符串13455與245576的最長公共子序列爲455。字符串acdfg與adfc的最長公共子序列爲adf。ios
注意區別最長公共子串(Longest Common Substring),最長公共字串要求連續。 spa
// ConsoleApplication20.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <algorithm> #include <stdlib.h> using namespace std; const int N = 250; int C[N][N]; int B[N][N]; enum Dir { LEFT = 1, TOP, LEFTTOP }; // 最長公共子序列 string targetStr; void PrintDir(Dir dir) { switch (dir) { case LEFT: cout << "-"; break; case TOP: cout << "|"; break; case LEFTTOP: cout << "\\"; break; default: cout << "0"; break; } cout << '\t'; } // 最長公共子序列長度 int LCS_L(const char* str1, const char* str2) { if (!str1 || !str2) return 0; const int str1Len = strlen(str1), str2Len = strlen(str2); const int len = max(str1Len, str2Len); for (int i = 0; i < len; i++) C[0][i] = C[i][0] = 0; for (int i = 1; i <= str1Len; i++) { for (int j = 1; j <= str2Len; j++) { if (str1[i-1] == str2[j-1]) { C[i][j] = C[i-1][j-1] + 1; B[i][j] = LEFTTOP; }else if (C[i-1][j] >= C[i][j-1]) { C[i][j] = C[i-1][j]; B[i][j] = TOP; } else { C[i][j] = C[i][j-1]; B[i][j] = LEFT; } // 當C[i-1][j] == C[i][j-1]時會出現多個最長公共子序列 } } // Debug /*for (int i = 0; i <= len; i++) { if (i == 0) { cout << '0' << '\t'; for (int k = 0; k < str2Len; k++) cout << str2[k] << '\t'; } else { if (i <= str1Len) cout << str1[i-1] << '\t'; else cout << '0' << '\t'; for (int j = 1; j <= len; j++) { //PrintDir(static_cast<Dir>(B[i][j])); cout << C[i][j] << "\t"; } } cout << endl << endl << endl << endl; } cout << "------------------------------------------------------" << endl; for (int i = 0; i <= len; i++) { if (i == 0) { cout << '0' << '\t'; for (int k = 0; k < str2Len; k++) cout << str2[k] << '\t'; } else { if (i <= str1Len) cout << str1[i - 1] << '\t'; else cout << '0' << '\t'; for (int j = 1; j <= len; j++) { PrintDir(static_cast<Dir>(B[i][j])); //cout << C[i][j] << "\t"; } } cout << endl << endl << endl << endl; } cout << "------------------------------------------------------" << endl;*/ return C[str1Len][str2Len]; } // 獲取最長公共子序列 void LCS(const char* str, int i, int j) { if (!str || i == 0 || j == 0) return; switch (B[i][j]) { case LEFT: LCS(str, i, j - 1); break; case LEFTTOP: cout << str[i - 1]; targetStr.insert(targetStr.begin(), str[i - 1]); LCS(str, i - 1, j - 1); break; case TOP: LCS(str, i - 1, j); break; default: break; } } int _tmain(int argc, _TCHAR* argv[]) { char str1[100], str2[100]; cin >> str1 >> str2; cout << LCS_L(str1, str2) << endl; LCS(str1, strlen(str1), strlen(str2)); cout << endl; cout << targetStr.c_str() << endl; return 0; }