LCS最长公共子序列
此算法是动态规划中的经典:
LCS即求数组 a b 中最长的公共子序列,其中序列不一定要相邻 。
用动态规划解有两种,一种是正着解,一种是倒着解,即备忘录法
贴下我写的代码:
int LCS(char a[],int la,char b[],int lb)
{
int** c = new int*[la+1];
int** path = new int*[la+1];
for(int i = 0;i<la+1;i++)
{
path[i] = new int[lb+1];
c[i] = new int[lb+1];
memset(path[i],0,sizeof(int)*lb);
memset(c[i],0,sizeof(int)*lb);
}
for(i = 1;i<=la;i++)
{
for(int j = 1;j<=lb;j++)
{
if(a[i-1] == b[j-1])
{
c[i][j] = 1+ c[i-1][j-1];
path[i][j] = 2;
}
else
{
if(c[i-1][j] >c[i][j-1])
{
c[i][j] = c[i-1][j];
path[i][j] = 1;
}
else
{
c[i][j] = c[i][j-1];
path[i][j] = 3;
}
}
}
}
int ttt= c[la][lb];
//print path
char* p = new char[ttt];
p = p+ttt;
int lla = la,llb = lb;
while(path[lla][llb] != 0)
{
if(path[lla][llb] == 2)
{
*(--p) = a[lla-1];
lla--;llb--;
}
else if(path[lla][llb] == 1)
{
lla--;
}
else //if (path[lla][llb] == 3)
{
llb--;
}
}
for(i = 0 ;i<ttt;i++)
cout<<p[i]<<" ";
cout<<endl;
delete [] p;
for( i = 0;i<la+1;i++)
{
delete [] path[i] ;
delete [] c[i];
path[i] = c[i] = NULL;
}
delete [] c;
delete [] path;
c = path = NULL;
return ttt;
}
void main()
{
char a[] = "a12b3c23d231`ah";
char b[]= "abcdefgh";
cout<<LCS(a,sizeof(a)-1,b,sizeof(b)-1);
}
{
int** c = new int*[la+1];
int** path = new int*[la+1];
for(int i = 0;i<la+1;i++)
{
path[i] = new int[lb+1];
c[i] = new int[lb+1];
memset(path[i],0,sizeof(int)*lb);
memset(c[i],0,sizeof(int)*lb);
}
for(i = 1;i<=la;i++)
{
for(int j = 1;j<=lb;j++)
{
if(a[i-1] == b[j-1])
{
c[i][j] = 1+ c[i-1][j-1];
path[i][j] = 2;
}
else
{
if(c[i-1][j] >c[i][j-1])
{
c[i][j] = c[i-1][j];
path[i][j] = 1;
}
else
{
c[i][j] = c[i][j-1];
path[i][j] = 3;
}
}
}
}
int ttt= c[la][lb];
//print path
char* p = new char[ttt];
p = p+ttt;
int lla = la,llb = lb;
while(path[lla][llb] != 0)
{
if(path[lla][llb] == 2)
{
*(--p) = a[lla-1];
lla--;llb--;
}
else if(path[lla][llb] == 1)
{
lla--;
}
else //if (path[lla][llb] == 3)
{
llb--;
}
}
for(i = 0 ;i<ttt;i++)
cout<<p[i]<<" ";
cout<<endl;
delete [] p;
for( i = 0;i<la+1;i++)
{
delete [] path[i] ;
delete [] c[i];
path[i] = c[i] = NULL;
}
delete [] c;
delete [] path;
c = path = NULL;
return ttt;
}
void main()
{
char a[] = "a12b3c23d231`ah";
char b[]= "abcdefgh";
cout<<LCS(a,sizeof(a)-1,b,sizeof(b)-1);
}