最长公共子串及其长度

来源:互联网 发布:立方米网络规模 编辑:程序博客网 时间:2024/05/16 11:55

求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;
}

原创粉丝点击