动态规划求解最长公共子序列
#include<iostream> #include<algorithm> using namespace std; void Print_LCS(int **b, string X,int m, int n); void LCS_Length(string X, string Y) { int m = X.length(); int n = Y.length(); X = "0" + X; Y = "0" + Y; int **b = new int*[m + 1]; for (int i = 0; i < m + 1; i++) { b[i] = new int[n + 1]; } int **c = new int*[m + 1]; for (int i = 0; i < m + 1;i++) { c[i] = new int[n + 1]; } for (int i = 1; i < m + 1; i++) c[i][0] = 0; for (int j = 0; j < n + 1; j++) c[0][j] = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (X.at(i) == Y.at(j)) { c[i][j] = c[i - 1][j - 1] + 1; b[i][j] = 1; } else if (c[i - 1][j]>=c[i][j - 1]) { c[i][j] = c[i - 1][j]; b[i][j] = 0; } else { c[i][j] = c[i][j - 1]; b[i][j] = -1; } } } Print_LCS(b,X,m,n); cout << "\n"; } void Print_LCS(int **b, string X,int m, int n) { if (m == 0 || n == 0) return; if (b[m][n] == 1) { Print_LCS(b,X,m-1,n-1); cout << X.at(m)<< " "; } else if (b[m][n] == 0) { Print_LCS(b,X, m - 1, n); } else { Print_LCS(b, X,m , n-1); } } //带有备忘的LCS_LENGTH int LoopUp_LCS(string X, string Y, int **C,int m, int n) { if (C[m][n] > -1) return C[m][n]; if (m == 0 || n == 0) C[m][n] = 0; else { if (X.at(m - 1) == Y.at(n - 1)) C[m][n] = LoopUp_LCS(X,Y,C,m-1,n-1) + 1; else { C[m][n] = max(LoopUp_LCS(X, Y, C, m - 1, n), LoopUp_LCS(X, Y, C, m, n-1)); } } return C[m][n]; } int**Memoized_LCS_Length(string X, string Y) { int m = X.length(); int n = Y.length(); X = "0" + X; Y = "0" + Y; int **C = new int*[m + 1]; for (int i = 0; i < m + 1; i++) { C[i] = new int[n + 1]; } for (int i = 0; i < m + 1; i++) { for (int j = 0; j < n + 1; j++) { C[i][j] = -1; } } LoopUp_LCS(X,Y,C,m,n); return C; } //KMP int *Compute2_Prefix_Function(string P,int m) { int *t = new int[m + 1]; t[1] = 0; int k = 0; for (int q = 2; q <= m; q++) { while (k > 0 && P[k + 1] != P[q]) k = t[k]; if (P[k + 1] == P[q]) k = k + 1; t[q] = k; } for (int i = 1; i <= m; i++) { cout << t[i] << " "; } cout << "\n"; return t; } void KMP2_Matcher(string T, string P) { int n = T.length(); int m = P.length(); T = "0" + T; P = "0" + P; int *t = Compute2_Prefix_Function(P, m); int q = 0; for (int i = 1; i <= n; i++) { while (q > 0 && P[q + 1] != T[i]) q = t[q]; if (P[q + 1] == T[i]) q = q + 1; if (q == m) { cout << "macther at " << i - m; q = t[q]; } } cout << "\n"; } int main() { string X = "ABCBDAB"; string Y = "BDCABA"; LCS_Length(X,Y); int **C = Memoized_LCS_Length(X, Y); for (unsigned i = 0; i < X.length() + 1; i++) { for (unsigned j = 0; j < Y.length(); j++) { cout << C[i][j] << "\t"; } cout << "\n"; } cout << "\n"; X = "ababababbc"; Y = "ababbc"; KMP2_Matcher(X,Y); return 0; }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 想让你多爱自己一些的开源计时器
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析