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

 

 

posted @ 2010-08-15 22:00  David Luo  阅读(239)  评论(0编辑  收藏  举报