一、最長公共子序列
#include<bits/stdc++.h>
#include<string>
#include<cstdio>
#include<iostream>
using namespace std;
string solve(string s1,string s2){
s1="*"+s1;
s2="&"+s2;
int n1=s1.size(),n2=s2.size();
int dp[n1+1][n2+1];
memset(dp,0,sizeof(dp));
string ans="";
for(int i=1;i<n1;i++){
for(int j=1;j<n2;j++){
if(s1[i]==s2[j]){
dp[i][j]=dp[i-1][j-1]+1;
}
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
n1-=1,n2-=1;
while(n1>=0&&n2>=0){
if(s1[n1]==s2[n2]){
ans+=s1[n1];
n1--;
n2--;
}
else if(dp[n1-1][n2]>dp[n1][n2-1])
n1-=1;
else
n2-=1;
}
reverse(ans.begin(),ans.end());
return ans;
}
int main()
{
string s1="12345EF",s2="1AB2345CD";
cout<<solve(s1,s2)<<endl;
return 0;
}
最後dp[n1-1][n2-1]就是最長公共子序列的長度
二:最長公共子串
最後maxx就是最長公共子串的長度,求出最長公共字串的長度之後,關鍵是怎麼返回去找到任意一個最長的子串,可以遍歷找到dp數組的最大值,一直往左上角走就是答案。
#include<bits/stdc++.h>
#include<string>
#include<cstdio>
#include<iostream>
using namespace std;
string solve(string s1,string s2){
s1="*"+s1;
s2="&"+s2;
int n1=s1.size(),n2=s2.size();
int dp[n1+1][n2+1];
memset(dp,0,sizeof(dp));
string ans="";
int maxx=-1,p=0,q=0;
for(int i=1;i<n1;i++){
for(int j=1;j<n2;j++){
if(s1[i]==s2[j]){
dp[i][j]=dp[i-1][j-1]+1;
}
else
dp[i][j]=0;
if(dp[i][j]>=maxx){
maxx=dp[i][j];
p=i;
q=j;
}
}
}
// cout<<p<<" "<<q<<endl;
while(p>=0&&q>=0){
if(s1[p]==s2[q]){
ans+=s1[p];
p--;
q--;
}
else
break;
}
reverse(ans.begin(),ans.end());
return ans;
}
int main()
{
string s1="12345EF",s2="1AB2345CD";
cout<<solve(s1,s2)<<endl;
return 0;
}
最長公共子串就是最近遇到的一個面試題。