现在有两个字符串s1,s2,它们的长度分别为l1,l2
我就直接写出递归式子
假如s1[i]=s2[j]时m[i][j]=m[i-1][j-1]+1,反之,m[i][j]=max(m[i-1][j],m[i][j-1]}
m[i][j]表示s1子串(从0到i位置的子串)与s2子串(从0到j位置子串)的最大公共子列长度
从上面看出来我们的存储空间需要l1,l2大小的空间,不过,我们可以看出来,我只使用三项m[i-][j-1],m[i-1][j],m[i][j-1],我们只要保存这三项即可,那么要多大的空间呢,当然是越小越好了。
如果说l1<l2,时,我从下面的代码来说明吧
for(int i=0;i<l2;i++)
for(int j=0;j<l1;j++)
m[i][j]=f(m[i-1][j-1],m[i-1][j],m[i][j-1]);
可以看出里面的递归关系每次变化只是一列的变化,所以只需要保留前面一列和当前列。
最后直接上源代码吧
int MaxSamelong(string s1,string s2)
{
vector<int> pre,cur;
string tmp;
if(s2.size()<s1.size())
{
tmp=s2;
s2=s1;
s1=tmp;
}
for(int i=0;i<s1.size();i++)
{
if(s2[0]==s1[i])
pre.push_back(1);
else
pre.push_back(0);
}
for(int i=0;i<s2.size();i++)
{
cur.push_back(pre[0]);
for(int j=1;j<s1.size();j++)
{
if(s1[j]==s2[i])
cur.push_back(pre[j-1]+1);
else
{
int k=pre[j];
if(k<cur[j-1])
k=cur[j-1];
cur.push_back(k);
}
}
pre=cur;
cur.clear();
}
return pre[s1.size()-1];
}
再上一个测试用例吧
int main()
{
string s1("sldjoiiiiu");
string s2("slkkkjou");
cout<<MaxSamelong(s1,s2);
return 0;
}