最长公共字串(Longest Common Substring)
1. 问题描述
2. 动态规划解
设 A 和 B 分别为长度为 m 和 n 的序列,用 opt[i, j] 表示 A[1 : i] 与 B[1 : j] 的且末位为 Ai (==Bj) 的公共子串的长度。则
- opt[0, j] = 0, opt[i, 0] = 0
- 如果 Ai == Bj, opt[i, j] = opt[i - 1, j - 1] + 1
- 如果 Ai!= Bj, opt[i, j] = 0
3. C++实现
// Longest Common Substring template<class Iter1, class Iter2> std::tuple<int, Iter1, Iter1> LCSstr(const Iter1 &beg1, const Iter1 &end1, const Iter2 &beg2, const Iter2 &end2) { int m = end1 - beg1; int n = end2 - beg2; std::vector<int> opt1(n + 1, 0); std::vector<int> opt2(n + 1, 0); Iter1 beg_opt = beg1; Iter2 end_opt = beg1; int length_opt = 0; Iter1 id1 = beg1; Iter2 id2; for(int i = 1; i <= m; ++i, ++id1) { id2 = beg2; for(int j = 1; j <= n; ++j, ++id2) { if(*id1 == *id2) { opt2[j] = opt1[j - 1] + 1; if(opt2[j] > length_opt) { length_opt = opt2[j]; end_opt = std::next(id1); } } else opt2[j] = 0; } if(i < m) opt1.swap(opt2); } beg_opt = std::prev(end_opt, length_opt); return std::make_tuple(length_opt, beg_opt, end_opt); }
4. 分析
空间复杂度 O(n)
时间复杂度 O(m * n)
老实为人,踏实为学