• 最长公共子序列(LCS)


    注意最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。比如字符串acdfg同akdfc的最长公共子串为df,而他们的最长公共子序列是adf。LCS可以使用动态规划法解决。

    学习了http://blog.csdn.net/v_july_v/article/details/6695482的思想,写了O(mn)的算法

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <cstdio>
    #define N 105
    using namespace std;
    int dp[N][N];
    string s[2];
    int s1,s2;
    int Max(int a,int b)
    {
        return a>b?a:b;
    }
    bool same(int i,int j)
    {
        if(s[0][i]==s[1][j])
            return true;
        return false;
    }
    //如果需要输出基于最长公共字串的两串合并,参考hdu1503的AC代码
    string solve()//输出最长公共字串
    {
        s1=-1,s2=-1;
        for(int i=0; i<N; i++) for(int j=0; j<N; j++) dp[i][j]=0;
        for(int i=s[0].length()-1; i>=0; i--)//自上而下遍历,方便还原的时候顺序还原
            for(int j=s[1].length()-1; j>=0; j--)
            {
                if(same(i,j))
                {
                    dp[i][j]=dp[i+1][j+1]+1;
                    if(s1==-1) s1=i;
                    s2=j;
           }
    else dp[i][j]=Max(dp[i+1][j],dp[i][j+1]); } string ans=""; int i=0,j=0; while(i<s[0].length()&&j<s[1].length()) { if(same(i,j)) ans+=s[0][i],i++,j++; else { if(dp[i][j+1]>dp[i+1][j]) j++; else i++; } } return ans; } int main() { while(cin>>s[0]>>s[1]) { cout<<solve()<<endl; } return 0; }
  • 相关阅读:
    网络基础,socket,黏包,socketserver
    面向对象基础、继承、反射
    模块导入,正则表达式,常见模块,异常处理
    函数基础,参数,内置函数
    文件操作
    运算符、数字、字符串、列表、字典、集合、小数据池
    python基础
    Linux
    Bioconda安装与使用
    Perl语言入门--5--散列、hash
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/6029837.html
Copyright © 2020-2023  润新知