最长公共子序列

港控/mmm° 2022-04-23 07:04 404阅读 0赞

最长公共子序列问题,具有最优子结构性质

  1. **设序列****X****m****=\{x****1****,x****2****,…,****x****m****\}****和****Y****n****=\{y****1****,y****2****,…,****y****n****\}****的最长公共子序列为****Z****k****=\{z****1****, z****2****,…,** **z****k****\}** **,则**

l 若**xm=yn zk=xm=y**n Z**k-1Xm-1 Yn-1的最长公共子序列。**

l 若**xm≠y**n z**k≠xm ZXm-1 Y 的最长公共子序列**

l 若**xm≠y**n z**k≠yn ZXm Y**n-1 的最长公共子序列

l

由此可见,**2个序列的最长公共子序列包含了这2**个序列的前缀的最长公共子序列。因此,最长公共子序列问题具有最优子结构性质

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpemlfZ2hx_size_16_color_FFFFFF_t_70

对应的代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. //最长公共子序列
  4. int main(){
  5. string a,b;
  6. cin>>a>>b;
  7. int c[100][100],n1=a.length(),n2=b.length();
  8. for(int i=1;i<=n1;i++)c[i][0]=0;//也就是说:a串中第i个字符和b串中第0个字符的公共子序列为长度为0;
  9. for(int i=1;i<=n2;i++)c[0][i]=0;//也就是说:b串中第i个字符和a串中第0个字符的公共子序列为长度为0;(注意抽象化)
  10. for(int i=1;i<=n1;i++)
  11. for(int j=1;j<=n2;j++)
  12. if(a[i-1]==b[j-1])c[i][j]=c[i-1][j-1]+1;
  13. else c[i][j]=max(c[i-1][j],c[i][j-1]);
  14. cout<<c[n1][n2];
  15. return 0;
  16. }

关于最长公共子序列的另外一类问题是输出它的最长公共子序列,这样只需要在每次更新c [ i ] [ j ]的时候,记录一下更新的种类

代码如下

void LCS**(**int i****int j**char *x**int **b)

{

if (**i ==0 || j==0) return;**

if (b[**i**][j]== 1)

{ LCS**(i-1j-1xb);**

  1. **printf****(“%c ”, x\[****i****\]); \}**

else

if (b[**i**][j]== 2)

  1. **LCS****(i-1****,****j****,****x****,****b);**

else

  1. **LCS****(****i****,****j-1****,****x****,****b);**

}

完整代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. void output(int i,int j,string a,string b){
  4. if(!i||!j)return 0;
  5. if(b[i][j]=1){
  6. output(i-1,j-1,a,b);
  7. cout<<a[i-1];
  8. }else if(b[i][j]==2){
  9. output(i-1,j,a,b);
  10. }else{
  11. output(i,j-1,a,b);
  12. }
  13. }
  14. int main(){
  15. string a,b;
  16. cin>>a>>b;
  17. int b[100][100],c[100][100],n1=a.length(),n2=b.length();
  18. for(int i=1;i<=n1;i++)c[i][0]=0;
  19. for(int i=1;i<=n2;i++)c[0][i]=0;
  20. for(int i=1;i<=n1;i++)
  21. for(int j=1;j<=n2;j++)
  22. if(a[i-1]==b[j-1]){
  23. c[i][j]=c[i-1][j-1]+1;
  24. b[i][j]=1;
  25. }else{
  26. if(c[i-1][j]>=c[i][j-1]){
  27. c[i][j]=c[i-1][j];
  28. b[i][j]=2;
  29. }else{
  30. c[i][j]=c[i][j-1];
  31. b[i][j]=3;
  32. }
  33. }
  34. }

发表评论

表情:
评论列表 (有 0 条评论,404人围观)

还没有评论,来说两句吧...

相关阅读

    相关 公共序列

    最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列

    相关 公共序列

    一个序列的子序列是该序列中删除某些元素后得到的序列。给定两个子序列X和Y,求二者的最长公共子序列。 例如,X=\{A,B,C,B,D,A,B\},Y=\{B,D,C,A,B,

    相关 公共序列

    最长公共子序列 最长公共子序列与最长公共子串的区别在于最长公共子序列不要求在原字符串中是连续的,比如ADE和ABCDE的最长公共子序列是ADE。 我们用动态规划的方法来思考