Longest Common Substring($LCS$)

Longest Common Substring(\(LCS\))

什么是子序列?

  子序列就是某一个序列的不连续的一部分.

如图, \(abcde\)就是图中序列的一个子序列。

公共子序列

  公共子序列的定义就是两个序列共有的子序列啦. qwq

一些题目就会要求我们求两个序列的最长公共子序列。

如果直接去两两比对的话,复杂度爆炸!

所以介绍\(O(n\times m)\)做法.

\(Dp\)

我们设\(f[i][j]\)代表从到达\(a\)串第\(i\)个位置,\(b\)串第\(j\)个位置的最长公共子序列的长度.

如何状态转移?

我们发现,如果要使我们的公共子序列的长度加长,必须要有的条件为\(a[i]==b[j]\)

因此,存在两种情况.

一. \(a[i]==a[j]\)

状态转移方程
\[
f[i][j]=f[i-1][j-1]+1
\]
这时直接继承上一个情况即可.

二.\(a[i]!=a[j]\)

此时需要考虑的是,我们依旧要进行状态的传递.

当前\(f[i][j]\)需要继承上一状态取到\(max\)。

那这里的上一状态是什么?

 我们可以知道的是,\(i-1\)位置与\(j\)位置已经有解,\(i\)位置与\(j-1\)位置已经有解。

如何去做?当前位置继承可以选择的状态也就是上面两种状态.

因此状态转移方程为
\[
f[i][j]=max(f[i-1][j],f[i][j-1])
\]
这样为什么正确?

我们当前位置为\(a\)串\(i\)和\(b\)串\(j\),最长公共子序列可能是\(a\)串\(i-1\)位置与\(b\)串\(j\)位置结合,

状态转移方程

\[\begin{cases}f[i][j]=f[i-1][j-1]+1 (a[i]==a[j]) \\f[i][j]=max(f[i-1][j],f[i][j-1]) (a[i]!=a[j])\\\end{cases}\]

由于当前位置\(i\)的状态只会与上一位置\(i-1\)有关,因此我们可以滚动数组.

滚动数组就不多BB了 emmm,

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define R register
using namespace std;
char a[5008],b[5008];
int lena,lenb;
int f[2][5008];
int main()
{
    scanf("%s%s",a+1,b+1);
    lena=strlen(a+1);
    lenb=strlen(b+1);
    for(R int i=1;i<=lena;i++)
    {
        int op=i&1;
        for(R int j=1;j<=lenb;j++)
        {
            if(a[i]==b[j])
                f[op][j]=f[op^1][j-1]+1;
            else
                f[op][j]=max(f[op^1][j],f[op][j-1]);
        }
    }
    printf("%d",f[lena&1][lenb]);
    return 0;
}

原文地址:https://www.cnblogs.com/-guz/p/9757012.html

时间: 2024-09-30 06:25:48

Longest Common Substring($LCS$)的相关文章

SPOJ 1811LCS Longest Common Substring

后缀自动机裸题.... Longest Common Substring Time Limit: 2000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is

HDU - 1403 - Longest Common Substring

先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4010    Accepted Submission(s): 1510 Problem Description Given two strings, you have to tell the length of the Long

hdu1403 Longest Common Substring

地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=1403 题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6296    Accepted Submission(s): 2249 Problem Description Give

[Algorithms] Longest Common Substring

The Longest Common Substring (LCS) problem is as follows: Given two strings s and t, find the length of the longest string r, which is a substring of both s and t. This problem is a classic application of Dynamic Programming. Let's define the sub-pro

后缀自动机(SAM) :SPOJ LCS - Longest Common Substring

LCS - Longest Common Substring no tags A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at

Longest Common Substring

Problem Statement Give two string $s_1$ and $s_2$, find the longest common substring (LCS). E.g: X = [111001], Y = [11011], the longest common substring is [110] with length 3. One terse way is to use Dynamic Programming (DP) to analyze the complex p

最长公共子串(Longest common substring)

问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子串.(子串中的字符要求连续) 这道题和最长公共子序列(Longest common subsequence)很像,也可以用动态规划定义.公式如下: 这里c[i,j]表示以Xi,Yj结尾的最长公共子串的长度. 程序实现: int longestCommonSubstring(string x, string y) { int m = x.length();

利用后缀数组(suffix array)求最长公共子串(longest common substring)

摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其重要的优势在于可以编码简单,代码易于理解,适合快速实现. 首先,来说明一下,LCS通常指的是公共最长子序列(Longest Common Subsequence,名称来源参见<算法导论>原书第3版p223),而不是公共最长子串(也称为最长公共子串). 最长公共子串问题是在文本串.模式串中寻找共有的

动态规划(二)最长公共子串(Longest Common Substring)

题目描述: 求两个输入序列的最长的公共子字符串的长度.子字符串中的所有字符在源字符串中必须相邻. 如字符串:21232523311324和字符串312123223445,他们的最长公共子字符串为21232,长度为5. 最长公共子串(Longest Common Substirng)和最长公共子序列(Longest Common Subsequence,LCS)的区别为: 子串是串的一个连续的部分,子序列则是从不改变序列的顺序,而从序列中去掉任意的元素而获得新的序列:也就是说,子串中字符的位置必须

【刷题】SPOJ 1811 LCS - Longest Common Substring

A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string. Now your task i