Q:给定两个字符串,输出两个字符串的最长公共子串及长度,如果没有公共子串则输出0
输入:
asd12asf
abd1asfba
输出:
3
asf
解题思路:
- 首先理解清楚最长公共子串和最长公共子序列的区别;最长公共子串要求子串是要连续的,而公共子序列不要求连续
- 建立二维数组,保存到该位置已经有几个字符串连续相等,初始化为0
- 如果s1[i]==s2[j],那么v[i][j]=v[i-1][j-1]+1;如果v[i][j]大于max,则更新最大长度,并记录此时在s1的下标(为了之后输出字符串)
- 最后得到的子串就是第一个字符串s1从记录的下标位置减去(最大长度-1)开始的max个字符
- 具体可以画图更好理解
代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string s1;
string s2;
while (getline(cin, s1) && getline(cin, s2))
{
int len1 = s1.length();
int len2 = s2.length();
vector<vector<int>> v(len1+1, vector<int>(len2+1,0)); //定义一个数组
int max = 0; //子串的最大长度
int start = -1; //记录下标位置
for (int i = 0; i < len1; ++i)
{
for (int j = 0; j < len2; ++j)
{
if (s1[i] == s2[j])
{
v[i + 1][j + 1] = v[i][j] + 1;
}
if (v[i + 1][j + 1] > max)
{
max = v[i + 1][j + 1];
start = i;
}
}
}
cout << max << endl;
string res = s1.substr(start-max+1, max); //获取子串
cout << res << endl;
}
return 0;
}
结果验证: