最长公共子串和最长公共序列

1. 最长公共子串

注意子串是连续的。有下列动态转移方程

c[i][j] = c[i-1][j-1] + 1   when X[i] = Y[j]

c[i][j] = 0   when X[i] != Y[j]

 1 c[100][100];
 2
 3 int LCS(char x[], int len_x, char y[], int len_y){
 4
 5        int max_len = 0;
 6
 7        for(int i =0; i < len_x ; i++){
 8            for(int j = 0; j < len_y;  j++){
 9                  if(x[i] == y[j]){
10                       if(x && y)
11                           c[i][j] = c[i-1][j-1] + 1;
12                       if(x == 0 || y == 0)
13                           c[i][j] = 1;
14                       if(c[i][j] > max_len)
15                            max_len = c[i][j];
16                 }
17            }
18       }
19
20       return max_len;
21 }    

2. 最长公共子序列

子序列不要求连续。

有下列状态转移方程

c[i][j] = c[i-1][j-1] + 1 if x[i] == y[j]

c[i][j] = max{c[i-1][j], c[i][j-1]} if x[i] != y[j]

// x = "+AB"   y = "+CD"

int c[100][100] = 0;

int lcs(char x[], char y[]){
     int m = strlen(x);
     int n = strlen(y);

     for(int i = 1; i<=m; i++)
       for(int j = 1; j <= n; j++){
             if(x[i] == y[j])
                   c[i][j] = c[i-1][j-1] + 1;
             else
                   c[i][j] = max(c[i][j-1], c[i-1][j]);
       }

    return c[m][n];
}
时间: 2024-10-03 14:41:49

最长公共子串和最长公共序列的相关文章

最长递增子序列 &amp;&amp; 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. 设dp[i]表示以i为结尾的最长递增子序列的长度,则状态转移方程为: dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i]. 这样简单的复杂度为O(n^2),其实还有更好的方

最长公共子串和最长公共子序列

最长公共子串与最长公共子序列是有区别的.区别在于最长公共子串要求字符是连续的. 例如:str1:  abcd      str2:  abec那么最长公共子序列是:abc,长度为3最长公共子串是:ab,长度为2 1. 最长公共子序列 Largest common subsequence 最长公共子序列:用f[i][j]表示str1的前i个字符与str2的前j个字符的最长公共子序列的长度. int LCS(int a[],int b[],int len) { vector<int> f(len+

最长连续公共子串、最长公共子串(可以非连续)、最长回文串(连续)、最长回文串(可以不连续)、最长递增数组的求解

问题:最长连续公共子串.最长公共子串(可以非连续).最长回文串(连续).最长回文串(可以不连续).最长递增数组.长方形镶嵌最多的求解 方法:上述问题有相似性,都可以采用动态规划进行求解. (1)最长连续公共子串: 如果A[i]==B[j], dp[i][j]=dp[i-1][j-1]+1; 否则,dp[i][j]=0; (2)最长公共子串(可非连续): 如果A[i]==B[j], dp[i][j]=dp[i-1][j-1]+1; 否则,dp[i][j]=dp[i-1][j-1]; (3)最长回文

最长公共子串、最长公共子序列的Java实现与NLP应用

前言以前HanLP使用"最短编辑距离"来做推荐器,效果有待提高,主要缺点是根据拼音序列的编辑距离推荐的时候,同音字交错很常见,而编辑距离却不那么大.这时我就在寻求一种补充的评分算法,去评判两个句子在拼音这一维度上的相似程度.区别最长公共子串(Longest Common Substring)指的是两个字符串中的最长公共子串,要求子串一定连续.最长公共子序列(Longest Common Substring)指的是两个字符串中的最长公共子串,不要求子串连续.求解两者的求解与编辑距离一样,

算法设计 - LCS 最长公共子序列&amp;&amp;最长公共子串 &amp;&amp;LIS 最长递增子序列

出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的最长公共子串方法.最长公共子串用动态规划可实现O(n^2)的时间复杂度,O(n^2)的空间复杂度:还可以进一步优化,用后缀数组的方法优化成线性时间O(nlogn):空间也可以用其他方法优化成线性.3.LIS(最长递增序列)DP方法可实现O(n^2)的时间复杂度,进一步优化最佳可达到O(nlogn)

最长公共子串与最长公共子序列之间的关系

最近工作中需要写一个算法,而写完这个算法我却发现了一个很有意思的事情.需要的这个算法是这样的:对于A,B两个字符串,找出最多K个公共子串,使得这K个子串长度和最大.一开始想了一些乱七八糟的想法. 错误想法1:比如每次找最长公共子串,找到一个子串后,从A,B两个字符串中删除这个子串,之后在剩下的串中再找最长公共子串,像这样找K次.但是可惜是错误的. 举个反例: A=KABCDELMABCDEFGNFGHIJK B=KABCDEFGHIJK K=2 按照这种方式选取结果为:ABCDEFG+HIJK,

最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

http://www.cnblogs.com/zhangchaoyang/articles/2012070.html 把一个问题转换为若干个规模更小的子问题,并且都借助于一个二维矩阵来实现计算. 约定:字符串S去掉最后一个字符T后为S',T1和T2分别是S1和S2的最后一个字符. 则dist(S1,S2)是下列4个值的最小者: 1.dist(S1',S2')--当T1==T2 2.1+dist(S1',S2)--当T1!=T2,并且删除S1的最后一个字符T1 3.1+dist(S1,S2')--

最长公共子串与最长公共子序列

一.最长公共子串(Longest Common Substring) 遍历的时候用一个二维数组存储相应位置的信息,如果两个子串1与子串2相应位置相等:则看各自前一个位置是否相等,相等则该位置值B[i][j]=B[i-1][j-1]+1,不相等则置为1.如果两个子串1与子串2相应位置不相等,则B[i][j]=0.如下:  代码如下: def longestSub(str1,str2): s1=list(str1) s2=list(str2) B=[([0]*len(s2)) for i in ra

最长对称子串 (最长回文字串) pta 7-12

题目链接https://pintia.cn/problem-sets/1218774283169423360/problems/1218774532776648715 方法一, 见代码 #include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include<cmath> #include<ve