本题是利用动态规划的经典题目。首先需要注意的是,公共子串和公共子序列的区别,子串要求是连续的,而子序列不要求是连续的,要求的是相对位置不能错。
由于是连续的,所以我们以较短的字符串为基准(外循环),依次判断各个字符和较长的字符串的各个字符是否相等,如果相等则将dp数组的对应位置表示为dp[i-1][j-1]+1,否则为0。
同时不断更新和比较最大值(对角线上的最大值),并记录公共子序列的右端位置下标。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
string s1, s2;
getline(cin, s1, '\n');
getline(cin, s2, '\n');
int max = 0;
int end = 0;
int flag = 0;
if (s1.size() <= s2.size()) flag = 1;
string s11, s22;
// 以较短的那个字符串作为判断的基准
if (flag) {
s11 = s1;
s22 = s2;
} else {
s11 = s2;
s22 = s1;
}
vector<vector<int>> dp(s11.size() + 1, vector<int>(s22.size() + 1, 0));
for (int i = 1; i <= s11.size(); i++) {
for (int j = 1; j <= s22.size(); j++) {
if (s11[i - 1] == s22[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
if (dp[i][j] > max) {
max = dp[i][j];
end = i - 1;
}
} else {
dp[i][j] = 0;
}
}
}
string res;
res = s11.substr(end - (max - 1), max);
cout << res << endl;
return 0;
}

京公网安备 11010502036488号