求2个串的最长公共子串及其长度
//
最长公共子串简称为lcs
// a[0]~a[i-1]的子串记为ai,a[0]~a[i-2]的子串记为a(i-1)
// b[0]~b[j-1]的子串记为bj,b[0]~b[j-2]的子串记为b(j-1)
#include < iostream >
#include < string >
#include < vector >
using namespace std;
string a; // 串a
int m; // 串a长度
string b; // 串b
int n; // 串b长度
// c[i][j]记录ai与bj的lcs的长度
vector < vector < int > > c; // lcs的长度记录在c[m][n]中
void lenOfLcs() // DP
{
for ( int i = 1 ;i <= m;i ++ )
{
for ( int j = 1 ;j <= n;j ++ )
{
if (a[i - 1 ] == b[j - 1 ])
c[i][j] = c[i - 1 ][j - 1 ] + 1 ; // 当前字符相等,lcs长度+1
else if (c[i - 1 ][j] >= c[i][j - 1 ]) // 当前字符不相等,lcs长度为max(c[i-1][j],c[i][j-1])
c[i][j] = c[i - 1 ][j];
else
c[i][j] = c[i][j - 1 ];
}
}
}
string lcs()
{
int i = m,j = n,k = c[m][n];
string s = "" ;
while (k > 0 )
{
if (c[i][j] == c[i - 1 ][j]) // ai与bj的lcs与a(i-1)与bj的lcs相同
i -- ;
else if (c[i][j] == c[i][j - 1 ]) // ai与bj的lcs与ai与b(j-1)的lcs相同
j -- ;
else
{
s = a[i - 1 ] + s; // +是连接符
k -- ;
i -- ;
j -- ;
}
}
return s;
}
bool run()
{
if ( ! (cin >> a >> b)) return false ;
m = a.size();
n = b.size();
c.resize(m + 1 );
for ( int i = 0 ;i <= m;i ++ )
{
c[i].resize(n + 1 );
c[i][ 0 ] = 0 ; // b串为空时,lcs的长度为0
}
for ( int j = 0 ;j <= n;j ++ )
c[ 0 ][j] = 0 ; // a串为空时,lcs的长度为0
lenOfLcs();
cout << " 最长公共子串的长度为: " << c[m][n] << endl;
cout << " 最长公共子串为: " << lcs() << endl;
return true ;
}
int main()
{
while (run());
return 0 ;
}
// a[0]~a[i-1]的子串记为ai,a[0]~a[i-2]的子串记为a(i-1)
// b[0]~b[j-1]的子串记为bj,b[0]~b[j-2]的子串记为b(j-1)
#include < iostream >
#include < string >
#include < vector >
using namespace std;
string a; // 串a
int m; // 串a长度
string b; // 串b
int n; // 串b长度
// c[i][j]记录ai与bj的lcs的长度
vector < vector < int > > c; // lcs的长度记录在c[m][n]中
void lenOfLcs() // DP
{
for ( int i = 1 ;i <= m;i ++ )
{
for ( int j = 1 ;j <= n;j ++ )
{
if (a[i - 1 ] == b[j - 1 ])
c[i][j] = c[i - 1 ][j - 1 ] + 1 ; // 当前字符相等,lcs长度+1
else if (c[i - 1 ][j] >= c[i][j - 1 ]) // 当前字符不相等,lcs长度为max(c[i-1][j],c[i][j-1])
c[i][j] = c[i - 1 ][j];
else
c[i][j] = c[i][j - 1 ];
}
}
}
string lcs()
{
int i = m,j = n,k = c[m][n];
string s = "" ;
while (k > 0 )
{
if (c[i][j] == c[i - 1 ][j]) // ai与bj的lcs与a(i-1)与bj的lcs相同
i -- ;
else if (c[i][j] == c[i][j - 1 ]) // ai与bj的lcs与ai与b(j-1)的lcs相同
j -- ;
else
{
s = a[i - 1 ] + s; // +是连接符
k -- ;
i -- ;
j -- ;
}
}
return s;
}
bool run()
{
if ( ! (cin >> a >> b)) return false ;
m = a.size();
n = b.size();
c.resize(m + 1 );
for ( int i = 0 ;i <= m;i ++ )
{
c[i].resize(n + 1 );
c[i][ 0 ] = 0 ; // b串为空时,lcs的长度为0
}
for ( int j = 0 ;j <= n;j ++ )
c[ 0 ][j] = 0 ; // a串为空时,lcs的长度为0
lenOfLcs();
cout << " 最长公共子串的长度为: " << c[m][n] << endl;
cout << " 最长公共子串为: " << lcs() << endl;
return true ;
}
int main()
{
while (run());
return 0 ;
}