链接:https://www.nowcoder.com/questionTerminal/181a1a71c7574266ad07f9739f791506
来源:牛客网
查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
输入描述:
输入两个字符串
输出描述:
返回重复出现的字符
示例1
输入
abcdefghijklmnop
abcsafjklmnopqrstuvw
输出
jklmnop
方法一:
直接遍历
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s1;
string s2;
while (cin >> s1 >> s2)
{
int len1 = s1.size();
int len2 = s2.size();
string tmp;
string ret;
if (len1 > len2)
{
swap(s1, s2);//保证s1是短串
}
int len = s1.size();
while (len)
{
for (int i = 0; i <= s1.size() - len; i++)
{
tmp = s1.substr(i, len);
/*if (strstr(s2.c_str(), tmp.c_str()))
{
ret = tmp;
break;
}*/
if (s2.find(tmp) != string::npos)
{
ret = tmp;
break;
}
}
if (ret.size() > 0)
{
break;
}
len--;
}
cout << ret << endl;
}
return 0;
}
方法二:
动态规划(牛客网上面同学的解法)
//思路:动态规划经典问题,加一个start标记即可,注意将较短子串最先出现的那个输出
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void findMaxCommonStr(string s1,string s2)
{
if(s1.length()>s2.length())
swap(s1,s2);//s1用于保存较短的子串
int len1=s1.length(),len2=s2.length();
int maxLen=0,start=0;
vector<vector<int> >dp(len1+1,vector<int>(len2+1,0));
for(int i=1;i<=len1;++i)
for(int j=1;j<=len2;++j)
{
if(s1[i-1]==s2[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
if(dp[i][j]>maxLen)
{
maxLen=dp[i][j];
start=i-maxLen;//记录最长公共子串的起始位置
}
}
}
cout<<s1.substr(start,maxLen)<<endl;
}
int main()
{
string s1,s2;
while(cin>>s1>>s2)
{
findMaxCommonStr(s1,s2);
}
return 0;
}