一、最长公共子序列
在两个字符串中,某一些字符都存在于两个串中,并且某些字符的前后顺序与在两个字符串的前后顺序相同,这些字符组成的串,就是两个字符串的公共子序列,其中最长的公共子序列,就是两个字符串的最长公共子序列(Longest Common Subsequence, LCS)
如下面的两个字符串:
abdkc
bdakmn
ak,bdk,bd都是两个字符串的公共子序列,其中bdk就是最长的公共子序列
二、核心思想
假设两个字符串: 和
求两个字符串的子串 和
的最长公共子序列
分为两种情况:
1、若 ,则最长公共子序列为
和
的最长公共子序列加上当前字符
2、,则最长公共子序列为
和
的最长公共子序列,或者为
和
的最长公共子序列
用二维数组表示的最长公共子序列的长度计算公式为:
三、代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int LCS(const string &str1,const string &str2);
int main()
{
string s1="abdkc";
string s2="bdakmn";
int len=LCS(s1,s2);
cout<<len<<endl;
return 0;
}
int LCS(const string &str1,const string &str2)
{
int len1=str1.size();
int len2=str2.size();
vector<vector<int>> result(len1+1,vector<int>(len2+1));
for(int i=0;i<=len1;i++)
for(int j=0;j<=len2;j++)
{
if(i==0||j==0) result[i][j]=0;
else if(str1[i-1]==str2[j-1]) result[i][j]=result[i-1][j-1]+1;
else result[i][j]=max(result[i][j-1],result[i-1][j]);
}
return result[len1][len2];
}
四、最长公共子串
和公共子序列不同的是,要求子串要是连续的,如下面的两个字符串:
abdkc
bdakmn
公共子串为bd,只有这一个子串,也为最长公共子串
五、计算公式
六、代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int sub_str(const string &str1,const string &str2);
int main()
{
string s1="abdkc";
string s2="bdakmn";
int len=sub_str(s1,s2);
cout<<len<<endl;
return 0;
}
int sub_str(const string &str1,const string &str2)
{
int len1=str1.size();
int len2=str2.size();
int max_result=0;
vector<vector<int>> result(len1+1,vector<int>(len2+1));
for(int i=0;i<=len1;i++)
for(int j=0;j<=len2;j++)
{
if(i==0||j==0) result[i][j]=0;
else if(str1[i-1]==str2[j-1])
{
result[i][j]=result[i-1][j-1]+1;
max_result=max(max_result,result[i][j]);
}
else result[i][j]=0;
}
return max_result;
}