题目描述
求两个子串的公共最长子序列(LCS)的长度。分析
该题是一道非常经典的动态规划题目。需要注意一些细节,不要阴沟里翻船(下文会提到)代码实现
我们可以得到如下的递归式,
若i=0或者j=0,c[i,j]=0;
若i,j>0并且xi=yj,c[i][j]=c[i-1][j-1]+1;
若i,j>0并且xi≠yj,c[i][j]=max(c[i][j-1],c[i-1][j]);
int LCSlen(string x,string y){
if(x==NULL||y==NULL)
return 0;
int m=x.size();
int n=y.size();
vector<vector<int> > c(m+1,vector<int>(n+1));
for(int i=1;i<m;i++)
c[i][0]=0;
for(int i=1;i<n;i++)
c[0][i]=0;
c[0][0]=0;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
if(x[i]==y[j])
c[i][j]=c[i-1][j-1]+1;
else
c[i][j]=max(c[i][j-1],c[i-1][j]);
}
return c[m][n];
}
细节注意
上述的代码其实是有问题的,不知道大家有没有注意到?
从表面现象来说,就是“234”和”sdfhhh“的输出结果为1,而非0。
为什么呢?
因为我们传入的数据类型是string,其最后还有一个‘\0’字符来作为字串的结束标志,所以在最后x[m]==y[n]的判断会为真,从而导致结果错误。怎么解决呢?
两种方法,
法一,把形参类型换为char X,char *Y类型,添加string转char 的代码。
法二,将if(x[i]==y[j])改为if(x[i]==y[j] && x[i]!=‘\0’)。