LCS(Longest Common Subsequence 最长公共子序列)

问题描述

最长公共子序列,英文缩写为LCS(Longest Com

#include <bits/stdc++.h>
const int MAX=1010;
char x[MAX];
char y[MAX];
int DP[MAX][MAX];
int b[MAX][MAX];
using namespace std;

int PRINT_LCS(int b[][MAX],char *x,int i,int j)
{
    if(i==0||j==0)
        return 1;
    if(b[i][j]==1)
    {
        PRINT_LCS(b,x,i-1,j-1);
        cout<<x[i]<<" ";
    }
    else if(b[i][j]==2)
    {
        PRINT_LCS(b,x,i-1,j);
    }
    else if(b[i][j]==3)
    {
        PRINT_LCS(b,x,i,j-1);
    }

}
int main()
{
    int T;
    int n,m,i,j;
    cin>>T;
    while(T--)
    {
        while(cin>>n>>m)
        {
            for(int i=1; i<=n; i++)
                cin>>x[i];
            for(int j=1; j<=m; j++)
                cin>>y[j];
            memset(DP,0,sizeof(DP));
            for(i=1; i<=n; i++)
            {
                for(j=1; j<=m; j++)
                {
                    if(x[i]==y[j])
                    {
                        DP[i][j]=DP[i-1][j-1]+1;
                        b[i][j]=1;
                    }

                    else if(DP[i-1][j]>=DP[i][j-1])
                    {
                        DP[i][j]=DP[i-1][j];
                        b[i][j]=2;
                    }
                    else
                    {
                        DP[i][j]=DP[i][j-1];//Max(DP[i-1][j],DP[i][j-1]);
                        b[i][j]=3;
                    }
                }
            }
            cout<<DP[n][m]<<endl;
            PRINT_LCS(b,x,n,m);
            cout<<endl;
        }
    }
    return 0;
}

mon Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。而最长公共子串(要求连续)和最长公共子序列是不同的

应用

最长公共子序列是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从而能够用来辨别抄袭。对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列外的部分提取出来,这种方法判断修改的部分,往往十分准确。简而言之,百度知道、百度百科都用得上。

动态规划

第一步:先计算最长公共子序列的长度。

第二步:根据长度,然后通过回溯求出最长公共子序列。

现有两个序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi},

设一个C[i,j]: 保存Xi与Yj的LCS的长度。

递推方程为:

代码亲测:

时间: 2024-12-25 14:08:05

LCS(Longest Common Subsequence 最长公共子序列)的相关文章

LCS修改版(Longest Common Subsequence 最长公共子序列)

题目描述 作为一名情报局特工,Nova君(2号)有着特殊的传达情报的技巧.为了避免被窃取情报,每次传达时,他都会发出两句旁人看来意义不明话,实际上暗号已经暗含其中.解密的方法很简单,分别从两句话里删掉任意多个字母,使得两句话剩余的部分相同,通过一定的删除手法,可以让剩余的部分相同且长度最大,就得到了可能的暗号.暗号可能有多个,还要进行筛选,现在情报局人手不够,希望你能助一臂之力,筛选工作不用你完成,你只需计算出暗号长度以及个数即可.(注意,字母的位置也是暗号的重要信息,位置不同的字母组成的暗号不

POJ 1458 Common Subsequence(最长公共子序列LCS)

POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列长度. 分析: 本题不用输出子序列,非常easy,直接处理就可以. 首先令dp[i][j]==x表示A串的前i个字符和B串的前j个字符的最长公共子序列长度为x. 初始化: dp全为0. 状态转移: IfA[i]==B[j] then dp[i][j]= dp[i-1][j-1]+1 else dp[

hdu 1159 Common Subsequence(最长公共子序列 DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25416    Accepted Submission(s): 11276 Problem Description A subsequence of

POJ 1458 Common Subsequence 最长公共子序列

题目大意:求两个字符串的最长公共子序列 题目思路:dp[i][j] 表示第一个字符串前i位 和 第二个字符串前j位的最长公共子序列 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f #define MAXSIZE 10

POJ 1458 Common Subsequence 最长公共子序列 LCS

LCS 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define clc(a,b) memset(a,b,sizeof(a)) 6 #define LL long long 7 #include<cmath> 8 using namespace std; 9 int dp[1010][1010];//表示到i-1,j-1的

hdu 1159 Common Subsequence(最长公共子序列 动态规划)

Common Subsequence Problem Description A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if

hdu 1159 Common Subsequence(最长公共子序列)

#include<bits/stdc++.h> using namespace std; int dp[1024][1024]; int main() { int i,j; char s1[1024],s2[1024]; while(~scanf("%s %s",s1,s2)) { memset(dp,0,sizeof(dp)); int len1=strlen(s1); int len2=strlen(s2); for(i=0;i<len1;i++) { for(j

UVA10100:Longest Match(最长公共子序列)&amp;&amp;HDU1458Common Subsequence ( LCS)

题目链接:http://blog.csdn.net/u014361775/article/details/42873875 题目解析: 给定两行字符串序列,输出它们之间最大公共子单词的个数 对于给的两个序列X 和 Y,用i 和 j分别作为它们的前缀指针,f[i][j]表示序列X的前缀Xi 和 序列Y的前缀Yi 的最长公共子序列的长度,在这道题中,可把每一个单词当作一个字符来进行比较. 当 i | j 为0时 ,此 f[i][j] = 0; 当 i!=0 && j!=0 &&

leetcode——Longest Common Prefix 最长公共前缀(AC)

Write a function to find the longest common prefix string amongst an array of strings. 其实做起来会感觉很简单,需要注意的是要考虑效率的问题,毕竟可能是很长的字符串数组,所以可以考虑选取所有字符串中最短的那个来首先进行比较,因为最长公共子串肯定不会大于其长度,这样避免了字符串之间长度差异很大造成的效率损失,然后每次比较之后最长公共子串的长度也永远不会大于最短的那个字符串,只会不变或减小,只要遍历字符串数组,挨个