题目描述:
如果Z既是X的子串,又是Y的子串,则称Z为X和Y的公共子串。
如果给定X、Y,求出最长Z及其长度。
注意:这里求的不是子序列,两者的意思并不相同。子串要求连续,子序列并不需要。
如果想要了解可以看这一篇最长子序列问题(LCS)--动态规划解法
示例:
输入
ABACCB
AACCAB
输出
ACC
3
分析:
dp[i][j]表示X从0到i与Y从0到j之间公共子串的长度。
代码:
//最长字串问题,不是最长子序列问题
#include<iostream>
#include<string>
using namespace std;const int N = 1000;
int dp[N][N] = { 0 };int main()
{string a, b;cin >> a;cin >> b;int lena = a.size();int lenb = b.size();int maxLen = 0;//最长字串长度int start = 0;//最长字串在a中的初始下标//本来要将dp[i][0]和dp[0][j]全都初始化,但是因为是0,所以可以省略//直接dpfor (int i = 0; i <lena; i++){for (int j = 0; j <lenb; j++){if (a[i] == b[j]){if (i > 0 && j > 0){dp[i][j] = dp[i - 1][j - 1] + 1;}else{dp[i][j] = 1;}}//如果a[i]!=b[i],则dp[i][j] = 0//这是因为子串要连续,走到i,j就断了这个连续。else{dp[i][j] = 0;//这步可以省略,因为初始值就是0;}if (dp[i][j] > maxLen){maxLen = dp[i][j];//更新最长字串长度start = i - maxLen + 1;//记录最长字串在a中的初始下标}}}cout << "dp数组为:" << endl;for (int i = 0; i < lena; i++){for (int j = 0; j < lenb; j++){cout << dp[i][j] << ' ';}cout << endl;}cout << "最长子串长度为:" << maxLen << endl;cout << "最长子串为" << a.substr(start, maxLen) << endl;system("pause");return 0;}